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 /* Initialize external pool data structures */
179 tf_init_tbl_pool(session);
181 session->ref_count++;
183 /* Return session ID */
184 parms->session_id = session->session_id;
187 "Session created, session_id:%d\n",
188 parms->session_id.id);
191 "domain:%d, bus:%d, device:%d, fw_session_id:%d\n",
192 parms->session_id.internal.domain,
193 parms->session_id.internal.bus,
194 parms->session_id.internal.device,
195 parms->session_id.internal.fw_session_id);
200 tfp_free(tfp->session->core_data);
201 tfp_free(tfp->session);
206 tf_close_session(tfp);
211 tf_attach_session(struct tf *tfp __rte_unused,
212 struct tf_attach_session_parms *parms __rte_unused)
220 /* - Open the shared memory for the attach_chan_name
221 * - Point to the shared session for this Device instance
222 * - Check that session is valid
223 * - Attach to the firmware so it can record there is more
224 * than one client of the session.
228 if (tfp->session->session_id.id != TF_SESSION_ID_INVALID) {
229 rc = tf_msg_session_attach(tfp,
230 parms->ctrl_chan_name,
234 #endif /* TF_SHARED */
239 tf_close_session(struct tf *tfp)
243 struct tf_session *tfs;
244 union tf_session_id session_id;
246 if (tfp == NULL || tfp->session == NULL)
249 tfs = (struct tf_session *)(tfp->session->core_data);
251 /* Cleanup if we're last user of the session */
252 if (tfs->ref_count == 1) {
253 /* Cleanup any outstanding resources */
254 rc_close = tf_rm_close(tfp);
257 if (tfs->session_id.id != TF_SESSION_ID_INVALID) {
258 rc = tf_msg_session_close(tfp);
262 "Message send failed, rc:%d\n",
266 /* Update the ref_count */
270 session_id = tfs->session_id;
272 /* Final cleanup as we're last user of the session */
273 if (tfs->ref_count == 0) {
274 tfp_free(tfp->session->core_data);
275 tfp_free(tfp->session);
280 "Session closed, session_id:%d\n",
284 "domain:%d, bus:%d, device:%d, fw_session_id:%d\n",
285 session_id.internal.domain,
286 session_id.internal.bus,
287 session_id.internal.device,
288 session_id.internal.fw_session_id);
293 /** insert EM hash entry API
299 int tf_insert_em_entry(struct tf *tfp,
300 struct tf_insert_em_entry_parms *parms)
302 struct tf_tbl_scope_cb *tbl_scope_cb;
304 if (tfp == NULL || parms == NULL)
308 tbl_scope_cb_find((struct tf_session *)tfp->session->core_data,
309 parms->tbl_scope_id);
310 if (tbl_scope_cb == NULL)
313 /* Process the EM entry per Table Scope type */
314 return tf_insert_eem_entry((struct tf_session *)tfp->session->core_data,
319 /** Delete EM hash entry API
325 int tf_delete_em_entry(struct tf *tfp,
326 struct tf_delete_em_entry_parms *parms)
328 struct tf_tbl_scope_cb *tbl_scope_cb;
330 if (tfp == NULL || parms == NULL)
334 tbl_scope_cb_find((struct tf_session *)tfp->session->core_data,
335 parms->tbl_scope_id);
336 if (tbl_scope_cb == NULL)
339 return tf_delete_eem_entry(tfp, parms);
342 /** allocate identifier resource
344 * Returns success or failure code.
346 int tf_alloc_identifier(struct tf *tfp,
347 struct tf_alloc_identifier_parms *parms)
349 struct bitalloc *session_pool;
350 struct tf_session *tfs;
354 if (parms == NULL || tfp == NULL)
357 if (tfp->session == NULL || tfp->session->core_data == NULL) {
358 PMD_DRV_LOG(ERR, "%s: session error\n",
359 tf_dir_2_str(parms->dir));
363 tfs = (struct tf_session *)(tfp->session->core_data);
365 switch (parms->ident_type) {
366 case TF_IDENT_TYPE_L2_CTXT:
367 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
368 TF_L2_CTXT_REMAP_POOL_NAME,
371 case TF_IDENT_TYPE_PROF_FUNC:
372 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
373 TF_PROF_FUNC_POOL_NAME,
376 case TF_IDENT_TYPE_EM_PROF:
377 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
378 TF_EM_PROF_ID_POOL_NAME,
381 case TF_IDENT_TYPE_WC_PROF:
382 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
383 TF_WC_TCAM_PROF_ID_POOL_NAME,
386 case TF_IDENT_TYPE_L2_FUNC:
387 PMD_DRV_LOG(ERR, "%s: unsupported %s\n",
388 tf_dir_2_str(parms->dir),
389 tf_ident_2_str(parms->ident_type));
393 PMD_DRV_LOG(ERR, "%s: %s\n",
394 tf_dir_2_str(parms->dir),
395 tf_ident_2_str(parms->ident_type));
401 PMD_DRV_LOG(ERR, "%s: identifier pool %s failure\n",
402 tf_dir_2_str(parms->dir),
403 tf_ident_2_str(parms->ident_type));
407 id = ba_alloc(session_pool);
410 PMD_DRV_LOG(ERR, "%s: %s: No resource available\n",
411 tf_dir_2_str(parms->dir),
412 tf_ident_2_str(parms->ident_type));
419 /** free identifier resource
421 * Returns success or failure code.
423 int tf_free_identifier(struct tf *tfp,
424 struct tf_free_identifier_parms *parms)
426 struct bitalloc *session_pool;
429 struct tf_session *tfs;
431 if (parms == NULL || tfp == NULL)
434 if (tfp->session == NULL || tfp->session->core_data == NULL) {
435 PMD_DRV_LOG(ERR, "%s: Session error\n",
436 tf_dir_2_str(parms->dir));
440 tfs = (struct tf_session *)(tfp->session->core_data);
442 switch (parms->ident_type) {
443 case TF_IDENT_TYPE_L2_CTXT:
444 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
445 TF_L2_CTXT_REMAP_POOL_NAME,
448 case TF_IDENT_TYPE_PROF_FUNC:
449 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
450 TF_PROF_FUNC_POOL_NAME,
453 case TF_IDENT_TYPE_EM_PROF:
454 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
455 TF_EM_PROF_ID_POOL_NAME,
458 case TF_IDENT_TYPE_WC_PROF:
459 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
460 TF_WC_TCAM_PROF_ID_POOL_NAME,
463 case TF_IDENT_TYPE_L2_FUNC:
464 PMD_DRV_LOG(ERR, "%s: unsupported %s\n",
465 tf_dir_2_str(parms->dir),
466 tf_ident_2_str(parms->ident_type));
470 PMD_DRV_LOG(ERR, "%s: invalid %s\n",
471 tf_dir_2_str(parms->dir),
472 tf_ident_2_str(parms->ident_type));
477 PMD_DRV_LOG(ERR, "%s: %s Identifier pool access failed\n",
478 tf_dir_2_str(parms->dir),
479 tf_ident_2_str(parms->ident_type));
483 ba_rc = ba_inuse(session_pool, (int)parms->id);
485 if (ba_rc == BA_FAIL || ba_rc == BA_ENTRY_FREE) {
486 PMD_DRV_LOG(ERR, "%s: %s: Entry %d already free",
487 tf_dir_2_str(parms->dir),
488 tf_ident_2_str(parms->ident_type),
493 ba_free(session_pool, (int)parms->id);
499 tf_alloc_tcam_entry(struct tf *tfp,
500 struct tf_alloc_tcam_entry_parms *parms)
504 struct tf_session *tfs;
505 struct bitalloc *session_pool;
507 if (parms == NULL || tfp == NULL)
510 if (tfp->session == NULL || tfp->session->core_data == NULL) {
511 PMD_DRV_LOG(ERR, "%s: session error\n",
512 tf_dir_2_str(parms->dir));
516 tfs = (struct tf_session *)(tfp->session->core_data);
518 rc = tf_rm_lookup_tcam_type_pool(tfs,
520 parms->tcam_tbl_type,
522 /* Error logging handled by tf_rm_lookup_tcam_type_pool */
526 index = ba_alloc(session_pool);
527 if (index == BA_FAIL) {
528 PMD_DRV_LOG(ERR, "%s: %s: No resource available\n",
529 tf_dir_2_str(parms->dir),
530 tf_tcam_tbl_2_str(parms->tcam_tbl_type));
539 tf_set_tcam_entry(struct tf *tfp,
540 struct tf_set_tcam_entry_parms *parms)
544 struct tf_session *tfs;
545 struct bitalloc *session_pool;
547 if (tfp == NULL || parms == NULL) {
548 PMD_DRV_LOG(ERR, "Invalid parameters\n");
552 if (tfp->session == NULL || tfp->session->core_data == NULL) {
554 "%s, Session info invalid\n",
555 tf_dir_2_str(parms->dir));
559 tfs = (struct tf_session *)(tfp->session->core_data);
562 * Each tcam send msg function should check for key sizes range
565 rc = tf_rm_lookup_tcam_type_pool(tfs,
567 parms->tcam_tbl_type,
569 /* Error logging handled by tf_rm_lookup_tcam_type_pool */
574 /* Verify that the entry has been previously allocated */
575 id = ba_inuse(session_pool, parms->idx);
578 "%s: %s: Invalid or not allocated index, idx:%d\n",
579 tf_dir_2_str(parms->dir),
580 tf_tcam_tbl_2_str(parms->tcam_tbl_type),
585 rc = tf_msg_tcam_entry_set(tfp, parms);
591 tf_get_tcam_entry(struct tf *tfp __rte_unused,
592 struct tf_get_tcam_entry_parms *parms __rte_unused)
594 int rc = -EOPNOTSUPP;
596 if (tfp == NULL || parms == NULL) {
597 PMD_DRV_LOG(ERR, "Invalid parameters\n");
601 if (tfp->session == NULL || tfp->session->core_data == NULL) {
603 "%s, Session info invalid\n",
604 tf_dir_2_str(parms->dir));
612 tf_free_tcam_entry(struct tf *tfp,
613 struct tf_free_tcam_entry_parms *parms)
616 struct tf_session *tfs;
617 struct bitalloc *session_pool;
619 if (parms == NULL || tfp == NULL)
622 if (tfp->session == NULL || tfp->session->core_data == NULL) {
623 PMD_DRV_LOG(ERR, "%s: Session error\n",
624 tf_dir_2_str(parms->dir));
628 tfs = (struct tf_session *)(tfp->session->core_data);
630 rc = tf_rm_lookup_tcam_type_pool(tfs,
632 parms->tcam_tbl_type,
634 /* Error logging handled by tf_rm_lookup_tcam_type_pool */
638 rc = ba_inuse(session_pool, (int)parms->idx);
639 if (rc == BA_FAIL || rc == BA_ENTRY_FREE) {
640 PMD_DRV_LOG(ERR, "%s: %s: Entry %d already free",
641 tf_dir_2_str(parms->dir),
642 tf_tcam_tbl_2_str(parms->tcam_tbl_type),
647 ba_free(session_pool, (int)parms->idx);
649 rc = tf_msg_tcam_entry_free(tfp, parms);
652 PMD_DRV_LOG(ERR, "%s: %s: Entry %d free failed",
653 tf_dir_2_str(parms->dir),
654 tf_tcam_tbl_2_str(parms->tcam_tbl_type),