1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2020 Broadcom
9 #include "tf_session.h"
18 static inline uint32_t SWAP_WORDS32(uint32_t val32)
20 return (((val32 & 0x0000ffff) << 16) |
21 ((val32 & 0xffff0000) >> 16));
24 static void tf_seeds_init(struct tf_session *session)
29 /* Initialize the lfsr */
32 /* RX and TX use the same seed values */
33 session->lkup_lkup3_init_cfg[TF_DIR_RX] =
34 session->lkup_lkup3_init_cfg[TF_DIR_TX] =
35 SWAP_WORDS32(rand32());
37 for (i = 0; i < TF_LKUP_SEED_MEM_SIZE / 2; i++) {
38 r = SWAP_WORDS32(rand32());
39 session->lkup_em_seed_mem[TF_DIR_RX][i * 2] = r;
40 session->lkup_em_seed_mem[TF_DIR_TX][i * 2] = r;
41 r = SWAP_WORDS32(rand32());
42 session->lkup_em_seed_mem[TF_DIR_RX][i * 2 + 1] = (r & 0x1);
43 session->lkup_em_seed_mem[TF_DIR_TX][i * 2 + 1] = (r & 0x1);
48 tf_open_session(struct tf *tfp,
49 struct tf_open_session_parms *parms)
52 struct tf_session *session;
53 struct tfp_calloc_parms alloc_parms;
54 unsigned int domain, bus, slot, device;
55 uint8_t fw_session_id;
57 if (tfp == NULL || parms == NULL)
60 /* Filter out any non-supported device types on the Core
61 * side. It is assumed that the Firmware will be supported if
62 * firmware open session succeeds.
64 if (parms->device_type != TF_DEVICE_TYPE_WH)
67 /* Build the beginning of session_id */
68 rc = sscanf(parms->ctrl_chan_name,
76 "Failed to scan device ctrl_chan_name\n");
80 /* open FW session and get a new session_id */
81 rc = tf_msg_session_open(tfp,
82 parms->ctrl_chan_name,
88 "Session is already open, rc:%d\n",
92 "Open message send failed, rc:%d\n",
95 parms->session_id.id = TF_FW_SESSION_ID_INVALID;
99 /* Allocate session */
100 alloc_parms.nitems = 1;
101 alloc_parms.size = sizeof(struct tf_session_info);
102 alloc_parms.alignment = 0;
103 rc = tfp_calloc(&alloc_parms);
107 "Failed to allocate session info, rc:%d\n",
112 tfp->session = (struct tf_session_info *)alloc_parms.mem_va;
114 /* Allocate core data for the session */
115 alloc_parms.nitems = 1;
116 alloc_parms.size = sizeof(struct tf_session);
117 alloc_parms.alignment = 0;
118 rc = tfp_calloc(&alloc_parms);
122 "Failed to allocate session data, rc:%d\n",
127 tfp->session->core_data = alloc_parms.mem_va;
129 session = (struct tf_session *)tfp->session->core_data;
130 tfp_memcpy(session->ctrl_chan_name,
131 parms->ctrl_chan_name,
132 TF_SESSION_NAME_MAX);
134 /* Initialize Session */
135 session->device_type = parms->device_type;
138 /* Construct the Session ID */
139 session->session_id.internal.domain = domain;
140 session->session_id.internal.bus = bus;
141 session->session_id.internal.device = device;
142 session->session_id.internal.fw_session_id = fw_session_id;
144 rc = tf_msg_session_qcfg(tfp);
148 "Query config message send failed, rc:%d\n",
153 /* Shadow DB configuration */
154 if (parms->shadow_copy) {
155 /* Ignore shadow_copy setting */
156 session->shadow_copy = 0;/* parms->shadow_copy; */
158 rc = tf_rm_shadow_db_init(tfs);
161 "Shadow DB Initialization failed\n, rc:%d",
163 /* Add additional processing */
164 #endif /* TF_SHADOW */
167 /* Adjust the Session with what firmware allowed us to get */
168 rc = tf_rm_allocate_validate(tfp);
174 /* Setup hash seeds */
175 tf_seeds_init(session);
177 /* Initialize external pool data structures */
178 tf_init_tbl_pool(session);
180 session->ref_count++;
182 /* Return session ID */
183 parms->session_id = session->session_id;
186 "Session created, session_id:%d\n",
187 parms->session_id.id);
190 "domain:%d, bus:%d, device:%d, fw_session_id:%d\n",
191 parms->session_id.internal.domain,
192 parms->session_id.internal.bus,
193 parms->session_id.internal.device,
194 parms->session_id.internal.fw_session_id);
199 tfp_free(tfp->session->core_data);
200 tfp_free(tfp->session);
205 tf_close_session(tfp);
210 tf_attach_session(struct tf *tfp __rte_unused,
211 struct tf_attach_session_parms *parms __rte_unused)
219 /* - Open the shared memory for the attach_chan_name
220 * - Point to the shared session for this Device instance
221 * - Check that session is valid
222 * - Attach to the firmware so it can record there is more
223 * than one client of the session.
227 if (tfp->session->session_id.id != TF_SESSION_ID_INVALID) {
228 rc = tf_msg_session_attach(tfp,
229 parms->ctrl_chan_name,
233 #endif /* TF_SHARED */
238 tf_close_session(struct tf *tfp)
242 struct tf_session *tfs;
243 union tf_session_id session_id;
245 if (tfp == NULL || tfp->session == NULL)
248 tfs = (struct tf_session *)(tfp->session->core_data);
250 /* Cleanup if we're last user of the session */
251 if (tfs->ref_count == 1) {
252 /* Cleanup any outstanding resources */
253 rc_close = tf_rm_close(tfp);
256 if (tfs->session_id.id != TF_SESSION_ID_INVALID) {
257 rc = tf_msg_session_close(tfp);
261 "Message send failed, rc:%d\n",
265 /* Update the ref_count */
269 session_id = tfs->session_id;
271 /* Final cleanup as we're last user of the session */
272 if (tfs->ref_count == 0) {
273 tfp_free(tfp->session->core_data);
274 tfp_free(tfp->session);
279 "Session closed, session_id:%d\n",
283 "domain:%d, bus:%d, device:%d, fw_session_id:%d\n",
284 session_id.internal.domain,
285 session_id.internal.bus,
286 session_id.internal.device,
287 session_id.internal.fw_session_id);
292 /** allocate identifier resource
294 * Returns success or failure code.
296 int tf_alloc_identifier(struct tf *tfp,
297 struct tf_alloc_identifier_parms *parms)
299 struct bitalloc *session_pool;
300 struct tf_session *tfs;
304 if (parms == NULL || tfp == NULL)
307 if (tfp->session == NULL || tfp->session->core_data == NULL) {
308 PMD_DRV_LOG(ERR, "%s: session error\n",
309 tf_dir_2_str(parms->dir));
313 tfs = (struct tf_session *)(tfp->session->core_data);
315 switch (parms->ident_type) {
316 case TF_IDENT_TYPE_L2_CTXT:
317 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
318 TF_L2_CTXT_REMAP_POOL_NAME,
321 case TF_IDENT_TYPE_PROF_FUNC:
322 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
323 TF_PROF_FUNC_POOL_NAME,
326 case TF_IDENT_TYPE_EM_PROF:
327 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
328 TF_EM_PROF_ID_POOL_NAME,
331 case TF_IDENT_TYPE_WC_PROF:
332 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
333 TF_WC_TCAM_PROF_ID_POOL_NAME,
336 case TF_IDENT_TYPE_L2_FUNC:
337 PMD_DRV_LOG(ERR, "%s: unsupported %s\n",
338 tf_dir_2_str(parms->dir),
339 tf_ident_2_str(parms->ident_type));
343 PMD_DRV_LOG(ERR, "%s: %s\n",
344 tf_dir_2_str(parms->dir),
345 tf_ident_2_str(parms->ident_type));
351 PMD_DRV_LOG(ERR, "%s: identifier pool %s failure\n",
352 tf_dir_2_str(parms->dir),
353 tf_ident_2_str(parms->ident_type));
357 id = ba_alloc(session_pool);
360 PMD_DRV_LOG(ERR, "%s: %s: No resource available\n",
361 tf_dir_2_str(parms->dir),
362 tf_ident_2_str(parms->ident_type));
369 /** free identifier resource
371 * Returns success or failure code.
373 int tf_free_identifier(struct tf *tfp,
374 struct tf_free_identifier_parms *parms)
376 struct bitalloc *session_pool;
379 struct tf_session *tfs;
381 if (parms == NULL || tfp == NULL)
384 if (tfp->session == NULL || tfp->session->core_data == NULL) {
385 PMD_DRV_LOG(ERR, "%s: Session error\n",
386 tf_dir_2_str(parms->dir));
390 tfs = (struct tf_session *)(tfp->session->core_data);
392 switch (parms->ident_type) {
393 case TF_IDENT_TYPE_L2_CTXT:
394 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
395 TF_L2_CTXT_REMAP_POOL_NAME,
398 case TF_IDENT_TYPE_PROF_FUNC:
399 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
400 TF_PROF_FUNC_POOL_NAME,
403 case TF_IDENT_TYPE_EM_PROF:
404 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
405 TF_EM_PROF_ID_POOL_NAME,
408 case TF_IDENT_TYPE_WC_PROF:
409 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
410 TF_WC_TCAM_PROF_ID_POOL_NAME,
413 case TF_IDENT_TYPE_L2_FUNC:
414 PMD_DRV_LOG(ERR, "%s: unsupported %s\n",
415 tf_dir_2_str(parms->dir),
416 tf_ident_2_str(parms->ident_type));
420 PMD_DRV_LOG(ERR, "%s: invalid %s\n",
421 tf_dir_2_str(parms->dir),
422 tf_ident_2_str(parms->ident_type));
427 PMD_DRV_LOG(ERR, "%s: %s Identifier pool access failed\n",
428 tf_dir_2_str(parms->dir),
429 tf_ident_2_str(parms->ident_type));
433 ba_rc = ba_inuse(session_pool, (int)parms->id);
435 if (ba_rc == BA_FAIL || ba_rc == BA_ENTRY_FREE) {
436 PMD_DRV_LOG(ERR, "%s: %s: Entry %d already free",
437 tf_dir_2_str(parms->dir),
438 tf_ident_2_str(parms->ident_type),
443 ba_free(session_pool, (int)parms->id);
449 tf_alloc_tcam_entry(struct tf *tfp,
450 struct tf_alloc_tcam_entry_parms *parms)
454 struct tf_session *tfs;
455 struct bitalloc *session_pool;
457 if (parms == NULL || tfp == NULL)
460 if (tfp->session == NULL || tfp->session->core_data == NULL) {
461 PMD_DRV_LOG(ERR, "%s: session error\n",
462 tf_dir_2_str(parms->dir));
466 tfs = (struct tf_session *)(tfp->session->core_data);
468 rc = tf_rm_lookup_tcam_type_pool(tfs,
470 parms->tcam_tbl_type,
472 /* Error logging handled by tf_rm_lookup_tcam_type_pool */
476 index = ba_alloc(session_pool);
477 if (index == BA_FAIL) {
478 PMD_DRV_LOG(ERR, "%s: %s: No resource available\n",
479 tf_dir_2_str(parms->dir),
480 tf_tcam_tbl_2_str(parms->tcam_tbl_type));
489 tf_set_tcam_entry(struct tf *tfp,
490 struct tf_set_tcam_entry_parms *parms)
494 struct tf_session *tfs;
495 struct bitalloc *session_pool;
497 if (tfp == NULL || parms == NULL) {
498 PMD_DRV_LOG(ERR, "Invalid parameters\n");
502 if (tfp->session == NULL || tfp->session->core_data == NULL) {
504 "%s, Session info invalid\n",
505 tf_dir_2_str(parms->dir));
509 tfs = (struct tf_session *)(tfp->session->core_data);
512 * Each tcam send msg function should check for key sizes range
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 */
524 /* Verify that the entry has been previously allocated */
525 id = ba_inuse(session_pool, parms->idx);
528 "%s: %s: Invalid or not allocated index, idx:%d\n",
529 tf_dir_2_str(parms->dir),
530 tf_tcam_tbl_2_str(parms->tcam_tbl_type),
535 rc = tf_msg_tcam_entry_set(tfp, parms);
541 tf_get_tcam_entry(struct tf *tfp __rte_unused,
542 struct tf_get_tcam_entry_parms *parms __rte_unused)
544 int rc = -EOPNOTSUPP;
546 if (tfp == NULL || parms == NULL) {
547 PMD_DRV_LOG(ERR, "Invalid parameters\n");
551 if (tfp->session == NULL || tfp->session->core_data == NULL) {
553 "%s, Session info invalid\n",
554 tf_dir_2_str(parms->dir));
562 tf_free_tcam_entry(struct tf *tfp,
563 struct tf_free_tcam_entry_parms *parms)
566 struct tf_session *tfs;
567 struct bitalloc *session_pool;
569 if (parms == NULL || tfp == NULL)
572 if (tfp->session == NULL || tfp->session->core_data == NULL) {
573 PMD_DRV_LOG(ERR, "%s: Session error\n",
574 tf_dir_2_str(parms->dir));
578 tfs = (struct tf_session *)(tfp->session->core_data);
580 rc = tf_rm_lookup_tcam_type_pool(tfs,
582 parms->tcam_tbl_type,
584 /* Error logging handled by tf_rm_lookup_tcam_type_pool */
588 rc = ba_inuse(session_pool, (int)parms->idx);
589 if (rc == BA_FAIL || rc == BA_ENTRY_FREE) {
590 PMD_DRV_LOG(ERR, "%s: %s: Entry %d already free",
591 tf_dir_2_str(parms->dir),
592 tf_tcam_tbl_2_str(parms->tcam_tbl_type),
597 ba_free(session_pool, (int)parms->idx);
599 rc = tf_msg_tcam_entry_free(tfp, parms);
602 PMD_DRV_LOG(ERR, "%s: %s: Entry %d free failed",
603 tf_dir_2_str(parms->dir),
604 tf_tcam_tbl_2_str(parms->tcam_tbl_type),