1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2020 Broadcom
9 #include "tf_session.h"
19 static inline uint32_t SWAP_WORDS32(uint32_t val32)
21 return (((val32 & 0x0000ffff) << 16) |
22 ((val32 & 0xffff0000) >> 16));
25 static void tf_seeds_init(struct tf_session *session)
30 /* Initialize the lfsr */
33 /* RX and TX use the same seed values */
34 session->lkup_lkup3_init_cfg[TF_DIR_RX] =
35 session->lkup_lkup3_init_cfg[TF_DIR_TX] =
36 SWAP_WORDS32(rand32());
38 for (i = 0; i < TF_LKUP_SEED_MEM_SIZE / 2; i++) {
39 r = SWAP_WORDS32(rand32());
40 session->lkup_em_seed_mem[TF_DIR_RX][i * 2] = r;
41 session->lkup_em_seed_mem[TF_DIR_TX][i * 2] = r;
42 r = SWAP_WORDS32(rand32());
43 session->lkup_em_seed_mem[TF_DIR_RX][i * 2 + 1] = (r & 0x1);
44 session->lkup_em_seed_mem[TF_DIR_TX][i * 2 + 1] = (r & 0x1);
49 tf_open_session(struct tf *tfp,
50 struct tf_open_session_parms *parms)
53 struct tf_session *session;
54 struct tfp_calloc_parms alloc_parms;
55 unsigned int domain, bus, slot, device;
56 uint8_t fw_session_id;
58 if (tfp == NULL || parms == NULL)
61 /* Filter out any non-supported device types on the Core
62 * side. It is assumed that the Firmware will be supported if
63 * firmware open session succeeds.
65 if (parms->device_type != TF_DEVICE_TYPE_WH)
68 /* Build the beginning of session_id */
69 rc = sscanf(parms->ctrl_chan_name,
77 "Failed to scan device ctrl_chan_name\n");
81 /* open FW session and get a new session_id */
82 rc = tf_msg_session_open(tfp,
83 parms->ctrl_chan_name,
89 "Session is already open, rc:%d\n",
93 "Open message send failed, rc:%d\n",
96 parms->session_id.id = TF_FW_SESSION_ID_INVALID;
100 /* Allocate session */
101 alloc_parms.nitems = 1;
102 alloc_parms.size = sizeof(struct tf_session_info);
103 alloc_parms.alignment = 0;
104 rc = tfp_calloc(&alloc_parms);
108 "Failed to allocate session info, rc:%d\n",
113 tfp->session = (struct tf_session_info *)alloc_parms.mem_va;
115 /* Allocate core data for the session */
116 alloc_parms.nitems = 1;
117 alloc_parms.size = sizeof(struct tf_session);
118 alloc_parms.alignment = 0;
119 rc = tfp_calloc(&alloc_parms);
123 "Failed to allocate session data, rc:%d\n",
128 tfp->session->core_data = alloc_parms.mem_va;
130 session = (struct tf_session *)tfp->session->core_data;
131 tfp_memcpy(session->ctrl_chan_name,
132 parms->ctrl_chan_name,
133 TF_SESSION_NAME_MAX);
135 /* Initialize Session */
136 session->device_type = parms->device_type;
139 /* Construct the Session ID */
140 session->session_id.internal.domain = domain;
141 session->session_id.internal.bus = bus;
142 session->session_id.internal.device = device;
143 session->session_id.internal.fw_session_id = fw_session_id;
145 rc = tf_msg_session_qcfg(tfp);
149 "Query config message send failed, rc:%d\n",
154 /* Shadow DB configuration */
155 if (parms->shadow_copy) {
156 /* Ignore shadow_copy setting */
157 session->shadow_copy = 0;/* parms->shadow_copy; */
159 rc = tf_rm_shadow_db_init(tfs);
162 "Shadow DB Initialization failed\n, rc:%d",
164 /* Add additional processing */
165 #endif /* TF_SHADOW */
168 /* Adjust the Session with what firmware allowed us to get */
169 rc = tf_rm_allocate_validate(tfp);
175 /* Setup hash seeds */
176 tf_seeds_init(session);
178 session->ref_count++;
180 /* Return session ID */
181 parms->session_id = session->session_id;
184 "Session created, session_id:%d\n",
185 parms->session_id.id);
188 "domain:%d, bus:%d, device:%d, fw_session_id:%d\n",
189 parms->session_id.internal.domain,
190 parms->session_id.internal.bus,
191 parms->session_id.internal.device,
192 parms->session_id.internal.fw_session_id);
197 tfp_free(tfp->session->core_data);
198 tfp_free(tfp->session);
203 tf_close_session(tfp);
208 tf_attach_session(struct tf *tfp __rte_unused,
209 struct tf_attach_session_parms *parms __rte_unused)
217 /* - Open the shared memory for the attach_chan_name
218 * - Point to the shared session for this Device instance
219 * - Check that session is valid
220 * - Attach to the firmware so it can record there is more
221 * than one client of the session.
225 if (tfp->session->session_id.id != TF_SESSION_ID_INVALID) {
226 rc = tf_msg_session_attach(tfp,
227 parms->ctrl_chan_name,
231 #endif /* TF_SHARED */
236 tf_close_session(struct tf *tfp)
240 struct tf_session *tfs;
241 union tf_session_id session_id;
243 if (tfp == NULL || tfp->session == NULL)
246 tfs = (struct tf_session *)(tfp->session->core_data);
248 /* Cleanup if we're last user of the session */
249 if (tfs->ref_count == 1) {
250 /* Cleanup any outstanding resources */
251 rc_close = tf_rm_close(tfp);
254 if (tfs->session_id.id != TF_SESSION_ID_INVALID) {
255 rc = tf_msg_session_close(tfp);
259 "Message send failed, rc:%d\n",
263 /* Update the ref_count */
267 session_id = tfs->session_id;
269 /* Final cleanup as we're last user of the session */
270 if (tfs->ref_count == 0) {
271 tfp_free(tfp->session->core_data);
272 tfp_free(tfp->session);
277 "Session closed, session_id:%d\n",
281 "domain:%d, bus:%d, device:%d, fw_session_id:%d\n",
282 session_id.internal.domain,
283 session_id.internal.bus,
284 session_id.internal.device,
285 session_id.internal.fw_session_id);
290 /** insert EM hash entry API
296 int tf_insert_em_entry(struct tf *tfp,
297 struct tf_insert_em_entry_parms *parms)
299 struct tf_tbl_scope_cb *tbl_scope_cb;
301 if (tfp == NULL || parms == NULL)
305 tbl_scope_cb_find((struct tf_session *)tfp->session->core_data,
306 parms->tbl_scope_id);
307 if (tbl_scope_cb == NULL)
310 /* Process the EM entry per Table Scope type */
311 return tf_insert_eem_entry((struct tf_session *)tfp->session->core_data,
316 /** Delete EM hash entry API
322 int tf_delete_em_entry(struct tf *tfp,
323 struct tf_delete_em_entry_parms *parms)
325 struct tf_tbl_scope_cb *tbl_scope_cb;
327 if (tfp == NULL || parms == NULL)
331 tbl_scope_cb_find((struct tf_session *)tfp->session->core_data,
332 parms->tbl_scope_id);
333 if (tbl_scope_cb == NULL)
336 return tf_delete_eem_entry(tfp, parms);
339 /** allocate identifier resource
341 * Returns success or failure code.
343 int tf_alloc_identifier(struct tf *tfp,
344 struct tf_alloc_identifier_parms *parms)
346 struct bitalloc *session_pool;
347 struct tf_session *tfs;
351 if (parms == NULL || tfp == NULL)
354 if (tfp->session == NULL || tfp->session->core_data == NULL) {
355 PMD_DRV_LOG(ERR, "%s: session error\n",
356 tf_dir_2_str(parms->dir));
360 tfs = (struct tf_session *)(tfp->session->core_data);
362 switch (parms->ident_type) {
363 case TF_IDENT_TYPE_L2_CTXT:
364 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
365 TF_L2_CTXT_REMAP_POOL_NAME,
368 case TF_IDENT_TYPE_PROF_FUNC:
369 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
370 TF_PROF_FUNC_POOL_NAME,
373 case TF_IDENT_TYPE_EM_PROF:
374 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
375 TF_EM_PROF_ID_POOL_NAME,
378 case TF_IDENT_TYPE_WC_PROF:
379 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
380 TF_WC_TCAM_PROF_ID_POOL_NAME,
383 case TF_IDENT_TYPE_L2_FUNC:
384 PMD_DRV_LOG(ERR, "%s: unsupported %s\n",
385 tf_dir_2_str(parms->dir),
386 tf_ident_2_str(parms->ident_type));
390 PMD_DRV_LOG(ERR, "%s: %s\n",
391 tf_dir_2_str(parms->dir),
392 tf_ident_2_str(parms->ident_type));
398 PMD_DRV_LOG(ERR, "%s: identifier pool %s failure\n",
399 tf_dir_2_str(parms->dir),
400 tf_ident_2_str(parms->ident_type));
404 id = ba_alloc(session_pool);
407 PMD_DRV_LOG(ERR, "%s: %s: No resource available\n",
408 tf_dir_2_str(parms->dir),
409 tf_ident_2_str(parms->ident_type));
416 /** free identifier resource
418 * Returns success or failure code.
420 int tf_free_identifier(struct tf *tfp,
421 struct tf_free_identifier_parms *parms)
423 struct bitalloc *session_pool;
426 struct tf_session *tfs;
428 if (parms == NULL || tfp == NULL)
431 if (tfp->session == NULL || tfp->session->core_data == NULL) {
432 PMD_DRV_LOG(ERR, "%s: Session error\n",
433 tf_dir_2_str(parms->dir));
437 tfs = (struct tf_session *)(tfp->session->core_data);
439 switch (parms->ident_type) {
440 case TF_IDENT_TYPE_L2_CTXT:
441 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
442 TF_L2_CTXT_REMAP_POOL_NAME,
445 case TF_IDENT_TYPE_PROF_FUNC:
446 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
447 TF_PROF_FUNC_POOL_NAME,
450 case TF_IDENT_TYPE_EM_PROF:
451 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
452 TF_EM_PROF_ID_POOL_NAME,
455 case TF_IDENT_TYPE_WC_PROF:
456 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
457 TF_WC_TCAM_PROF_ID_POOL_NAME,
460 case TF_IDENT_TYPE_L2_FUNC:
461 PMD_DRV_LOG(ERR, "%s: unsupported %s\n",
462 tf_dir_2_str(parms->dir),
463 tf_ident_2_str(parms->ident_type));
467 PMD_DRV_LOG(ERR, "%s: invalid %s\n",
468 tf_dir_2_str(parms->dir),
469 tf_ident_2_str(parms->ident_type));
474 PMD_DRV_LOG(ERR, "%s: %s Identifier pool access failed\n",
475 tf_dir_2_str(parms->dir),
476 tf_ident_2_str(parms->ident_type));
480 ba_rc = ba_inuse(session_pool, (int)parms->id);
482 if (ba_rc == BA_FAIL || ba_rc == BA_ENTRY_FREE) {
483 PMD_DRV_LOG(ERR, "%s: %s: Entry %d already free",
484 tf_dir_2_str(parms->dir),
485 tf_ident_2_str(parms->ident_type),
490 ba_free(session_pool, (int)parms->id);
496 tf_alloc_tcam_entry(struct tf *tfp,
497 struct tf_alloc_tcam_entry_parms *parms)
501 struct tf_session *tfs;
502 struct bitalloc *session_pool;
504 if (parms == NULL || tfp == NULL)
507 if (tfp->session == NULL || tfp->session->core_data == NULL) {
508 PMD_DRV_LOG(ERR, "%s: session error\n",
509 tf_dir_2_str(parms->dir));
513 tfs = (struct tf_session *)(tfp->session->core_data);
515 rc = tf_rm_lookup_tcam_type_pool(tfs,
517 parms->tcam_tbl_type,
519 /* Error logging handled by tf_rm_lookup_tcam_type_pool */
523 index = ba_alloc(session_pool);
524 if (index == BA_FAIL) {
525 PMD_DRV_LOG(ERR, "%s: %s: No resource available\n",
526 tf_dir_2_str(parms->dir),
527 tf_tcam_tbl_2_str(parms->tcam_tbl_type));
536 tf_set_tcam_entry(struct tf *tfp,
537 struct tf_set_tcam_entry_parms *parms)
541 struct tf_session *tfs;
542 struct bitalloc *session_pool;
544 if (tfp == NULL || parms == NULL) {
545 PMD_DRV_LOG(ERR, "Invalid parameters\n");
549 if (tfp->session == NULL || tfp->session->core_data == NULL) {
551 "%s, Session info invalid\n",
552 tf_dir_2_str(parms->dir));
556 tfs = (struct tf_session *)(tfp->session->core_data);
559 * Each tcam send msg function should check for key sizes range
562 rc = tf_rm_lookup_tcam_type_pool(tfs,
564 parms->tcam_tbl_type,
566 /* Error logging handled by tf_rm_lookup_tcam_type_pool */
571 /* Verify that the entry has been previously allocated */
572 id = ba_inuse(session_pool, parms->idx);
575 "%s: %s: Invalid or not allocated index, idx:%d\n",
576 tf_dir_2_str(parms->dir),
577 tf_tcam_tbl_2_str(parms->tcam_tbl_type),
582 rc = tf_msg_tcam_entry_set(tfp, parms);
588 tf_get_tcam_entry(struct tf *tfp __rte_unused,
589 struct tf_get_tcam_entry_parms *parms __rte_unused)
591 int rc = -EOPNOTSUPP;
593 if (tfp == NULL || parms == NULL) {
594 PMD_DRV_LOG(ERR, "Invalid parameters\n");
598 if (tfp->session == NULL || tfp->session->core_data == NULL) {
600 "%s, Session info invalid\n",
601 tf_dir_2_str(parms->dir));
609 tf_free_tcam_entry(struct tf *tfp,
610 struct tf_free_tcam_entry_parms *parms)
613 struct tf_session *tfs;
614 struct bitalloc *session_pool;
616 if (parms == NULL || tfp == NULL)
619 if (tfp->session == NULL || tfp->session->core_data == NULL) {
620 PMD_DRV_LOG(ERR, "%s: Session error\n",
621 tf_dir_2_str(parms->dir));
625 tfs = (struct tf_session *)(tfp->session->core_data);
627 rc = tf_rm_lookup_tcam_type_pool(tfs,
629 parms->tcam_tbl_type,
631 /* Error logging handled by tf_rm_lookup_tcam_type_pool */
635 rc = ba_inuse(session_pool, (int)parms->idx);
636 if (rc == BA_FAIL || rc == BA_ENTRY_FREE) {
637 PMD_DRV_LOG(ERR, "%s: %s: Entry %d already free",
638 tf_dir_2_str(parms->dir),
639 tf_tcam_tbl_2_str(parms->tcam_tbl_type),
644 ba_free(session_pool, (int)parms->idx);
646 rc = tf_msg_tcam_entry_free(tfp, parms);
649 PMD_DRV_LOG(ERR, "%s: %s: Entry %d free failed",
650 tf_dir_2_str(parms->dir),
651 tf_tcam_tbl_2_str(parms->tcam_tbl_type),