1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2020 Broadcom
9 #include "tf_session.h"
17 static inline uint32_t SWAP_WORDS32(uint32_t val32)
19 return (((val32 & 0x0000ffff) << 16) |
20 ((val32 & 0xffff0000) >> 16));
23 static void tf_seeds_init(struct tf_session *session)
28 /* Initialize the lfsr */
31 /* RX and TX use the same seed values */
32 session->lkup_lkup3_init_cfg[TF_DIR_RX] =
33 session->lkup_lkup3_init_cfg[TF_DIR_TX] =
34 SWAP_WORDS32(rand32());
36 for (i = 0; i < TF_LKUP_SEED_MEM_SIZE / 2; i++) {
37 r = SWAP_WORDS32(rand32());
38 session->lkup_em_seed_mem[TF_DIR_RX][i * 2] = r;
39 session->lkup_em_seed_mem[TF_DIR_TX][i * 2] = r;
40 r = SWAP_WORDS32(rand32());
41 session->lkup_em_seed_mem[TF_DIR_RX][i * 2 + 1] = (r & 0x1);
42 session->lkup_em_seed_mem[TF_DIR_TX][i * 2 + 1] = (r & 0x1);
47 tf_open_session(struct tf *tfp,
48 struct tf_open_session_parms *parms)
51 struct tf_session *session;
52 struct tfp_calloc_parms alloc_parms;
53 unsigned int domain, bus, slot, device;
54 uint8_t fw_session_id;
56 if (tfp == NULL || parms == NULL)
59 /* Filter out any non-supported device types on the Core
60 * side. It is assumed that the Firmware will be supported if
61 * firmware open session succeeds.
63 if (parms->device_type != TF_DEVICE_TYPE_WH)
66 /* Build the beginning of session_id */
67 rc = sscanf(parms->ctrl_chan_name,
75 "Failed to scan device ctrl_chan_name\n");
79 /* open FW session and get a new session_id */
80 rc = tf_msg_session_open(tfp,
81 parms->ctrl_chan_name,
87 "Session is already open, rc:%d\n",
91 "Open message send failed, rc:%d\n",
94 parms->session_id.id = TF_FW_SESSION_ID_INVALID;
98 /* Allocate session */
99 alloc_parms.nitems = 1;
100 alloc_parms.size = sizeof(struct tf_session_info);
101 alloc_parms.alignment = 0;
102 rc = tfp_calloc(&alloc_parms);
106 "Failed to allocate session info, rc:%d\n",
111 tfp->session = (struct tf_session_info *)alloc_parms.mem_va;
113 /* Allocate core data for the session */
114 alloc_parms.nitems = 1;
115 alloc_parms.size = sizeof(struct tf_session);
116 alloc_parms.alignment = 0;
117 rc = tfp_calloc(&alloc_parms);
121 "Failed to allocate session data, rc:%d\n",
126 tfp->session->core_data = alloc_parms.mem_va;
128 session = (struct tf_session *)tfp->session->core_data;
129 tfp_memcpy(session->ctrl_chan_name,
130 parms->ctrl_chan_name,
131 TF_SESSION_NAME_MAX);
133 /* Initialize Session */
134 session->device_type = parms->device_type;
137 /* Construct the Session ID */
138 session->session_id.internal.domain = domain;
139 session->session_id.internal.bus = bus;
140 session->session_id.internal.device = device;
141 session->session_id.internal.fw_session_id = fw_session_id;
143 rc = tf_msg_session_qcfg(tfp);
147 "Query config message send failed, rc:%d\n",
152 /* Shadow DB configuration */
153 if (parms->shadow_copy) {
154 /* Ignore shadow_copy setting */
155 session->shadow_copy = 0;/* parms->shadow_copy; */
157 rc = tf_rm_shadow_db_init(tfs);
160 "Shadow DB Initialization failed\n, rc:%d",
162 /* Add additional processing */
163 #endif /* TF_SHADOW */
166 /* Adjust the Session with what firmware allowed us to get */
167 rc = tf_rm_allocate_validate(tfp);
173 /* Setup hash seeds */
174 tf_seeds_init(session);
176 session->ref_count++;
178 /* Return session ID */
179 parms->session_id = session->session_id;
182 "Session created, session_id:%d\n",
183 parms->session_id.id);
186 "domain:%d, bus:%d, device:%d, fw_session_id:%d\n",
187 parms->session_id.internal.domain,
188 parms->session_id.internal.bus,
189 parms->session_id.internal.device,
190 parms->session_id.internal.fw_session_id);
195 tfp_free(tfp->session->core_data);
196 tfp_free(tfp->session);
201 tf_close_session(tfp);
206 tf_attach_session(struct tf *tfp __rte_unused,
207 struct tf_attach_session_parms *parms __rte_unused)
215 /* - Open the shared memory for the attach_chan_name
216 * - Point to the shared session for this Device instance
217 * - Check that session is valid
218 * - Attach to the firmware so it can record there is more
219 * than one client of the session.
223 if (tfp->session->session_id.id != TF_SESSION_ID_INVALID) {
224 rc = tf_msg_session_attach(tfp,
225 parms->ctrl_chan_name,
229 #endif /* TF_SHARED */
234 tf_close_session(struct tf *tfp)
238 struct tf_session *tfs;
239 union tf_session_id session_id;
241 if (tfp == NULL || tfp->session == NULL)
244 tfs = (struct tf_session *)(tfp->session->core_data);
246 /* Cleanup if we're last user of the session */
247 if (tfs->ref_count == 1) {
248 /* Cleanup any outstanding resources */
249 rc_close = tf_rm_close(tfp);
252 if (tfs->session_id.id != TF_SESSION_ID_INVALID) {
253 rc = tf_msg_session_close(tfp);
257 "Message send failed, rc:%d\n",
261 /* Update the ref_count */
265 session_id = tfs->session_id;
267 /* Final cleanup as we're last user of the session */
268 if (tfs->ref_count == 0) {
269 tfp_free(tfp->session->core_data);
270 tfp_free(tfp->session);
275 "Session closed, session_id:%d\n",
279 "domain:%d, bus:%d, device:%d, fw_session_id:%d\n",
280 session_id.internal.domain,
281 session_id.internal.bus,
282 session_id.internal.device,
283 session_id.internal.fw_session_id);
288 /** allocate identifier resource
290 * Returns success or failure code.
292 int tf_alloc_identifier(struct tf *tfp,
293 struct tf_alloc_identifier_parms *parms)
295 struct bitalloc *session_pool;
296 struct tf_session *tfs;
300 if (parms == NULL || tfp == NULL)
303 if (tfp->session == NULL || tfp->session->core_data == NULL) {
304 PMD_DRV_LOG(ERR, "%s: session error\n",
305 tf_dir_2_str(parms->dir));
309 tfs = (struct tf_session *)(tfp->session->core_data);
311 switch (parms->ident_type) {
312 case TF_IDENT_TYPE_L2_CTXT:
313 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
314 TF_L2_CTXT_REMAP_POOL_NAME,
317 case TF_IDENT_TYPE_PROF_FUNC:
318 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
319 TF_PROF_FUNC_POOL_NAME,
322 case TF_IDENT_TYPE_EM_PROF:
323 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
324 TF_EM_PROF_ID_POOL_NAME,
327 case TF_IDENT_TYPE_WC_PROF:
328 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
329 TF_WC_TCAM_PROF_ID_POOL_NAME,
332 case TF_IDENT_TYPE_L2_FUNC:
333 PMD_DRV_LOG(ERR, "%s: unsupported %s\n",
334 tf_dir_2_str(parms->dir),
335 tf_ident_2_str(parms->ident_type));
339 PMD_DRV_LOG(ERR, "%s: %s\n",
340 tf_dir_2_str(parms->dir),
341 tf_ident_2_str(parms->ident_type));
347 PMD_DRV_LOG(ERR, "%s: identifier pool %s failure\n",
348 tf_dir_2_str(parms->dir),
349 tf_ident_2_str(parms->ident_type));
353 id = ba_alloc(session_pool);
356 PMD_DRV_LOG(ERR, "%s: %s: No resource available\n",
357 tf_dir_2_str(parms->dir),
358 tf_ident_2_str(parms->ident_type));
365 /** free identifier resource
367 * Returns success or failure code.
369 int tf_free_identifier(struct tf *tfp,
370 struct tf_free_identifier_parms *parms)
372 struct bitalloc *session_pool;
375 struct tf_session *tfs;
377 if (parms == NULL || tfp == NULL)
380 if (tfp->session == NULL || tfp->session->core_data == NULL) {
381 PMD_DRV_LOG(ERR, "%s: Session error\n",
382 tf_dir_2_str(parms->dir));
386 tfs = (struct tf_session *)(tfp->session->core_data);
388 switch (parms->ident_type) {
389 case TF_IDENT_TYPE_L2_CTXT:
390 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
391 TF_L2_CTXT_REMAP_POOL_NAME,
394 case TF_IDENT_TYPE_PROF_FUNC:
395 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
396 TF_PROF_FUNC_POOL_NAME,
399 case TF_IDENT_TYPE_EM_PROF:
400 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
401 TF_EM_PROF_ID_POOL_NAME,
404 case TF_IDENT_TYPE_WC_PROF:
405 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
406 TF_WC_TCAM_PROF_ID_POOL_NAME,
409 case TF_IDENT_TYPE_L2_FUNC:
410 PMD_DRV_LOG(ERR, "%s: unsupported %s\n",
411 tf_dir_2_str(parms->dir),
412 tf_ident_2_str(parms->ident_type));
416 PMD_DRV_LOG(ERR, "%s: invalid %s\n",
417 tf_dir_2_str(parms->dir),
418 tf_ident_2_str(parms->ident_type));
423 PMD_DRV_LOG(ERR, "%s: %s Identifier pool access failed\n",
424 tf_dir_2_str(parms->dir),
425 tf_ident_2_str(parms->ident_type));
429 ba_rc = ba_inuse(session_pool, (int)parms->id);
431 if (ba_rc == BA_FAIL || ba_rc == BA_ENTRY_FREE) {
432 PMD_DRV_LOG(ERR, "%s: %s: Entry %d already free",
433 tf_dir_2_str(parms->dir),
434 tf_ident_2_str(parms->ident_type),
439 ba_free(session_pool, (int)parms->id);
445 tf_alloc_tcam_entry(struct tf *tfp,
446 struct tf_alloc_tcam_entry_parms *parms)
450 struct tf_session *tfs;
451 struct bitalloc *session_pool;
453 if (parms == NULL || tfp == NULL)
456 if (tfp->session == NULL || tfp->session->core_data == NULL) {
457 PMD_DRV_LOG(ERR, "%s: session error\n",
458 tf_dir_2_str(parms->dir));
462 tfs = (struct tf_session *)(tfp->session->core_data);
464 rc = tf_rm_lookup_tcam_type_pool(tfs,
466 parms->tcam_tbl_type,
468 /* Error logging handled by tf_rm_lookup_tcam_type_pool */
472 index = ba_alloc(session_pool);
473 if (index == BA_FAIL) {
474 PMD_DRV_LOG(ERR, "%s: %s: No resource available\n",
475 tf_dir_2_str(parms->dir),
476 tf_tcam_tbl_2_str(parms->tcam_tbl_type));
485 tf_set_tcam_entry(struct tf *tfp,
486 struct tf_set_tcam_entry_parms *parms)
490 struct tf_session *tfs;
491 struct bitalloc *session_pool;
493 if (tfp == NULL || parms == NULL) {
494 PMD_DRV_LOG(ERR, "Invalid parameters\n");
498 if (tfp->session == NULL || tfp->session->core_data == NULL) {
500 "%s, Session info invalid\n",
501 tf_dir_2_str(parms->dir));
505 tfs = (struct tf_session *)(tfp->session->core_data);
508 * Each tcam send msg function should check for key sizes range
511 rc = tf_rm_lookup_tcam_type_pool(tfs,
513 parms->tcam_tbl_type,
515 /* Error logging handled by tf_rm_lookup_tcam_type_pool */
520 /* Verify that the entry has been previously allocated */
521 id = ba_inuse(session_pool, parms->idx);
524 "%s: %s: Invalid or not allocated index, idx:%d\n",
525 tf_dir_2_str(parms->dir),
526 tf_tcam_tbl_2_str(parms->tcam_tbl_type),
531 rc = tf_msg_tcam_entry_set(tfp, parms);
537 tf_get_tcam_entry(struct tf *tfp __rte_unused,
538 struct tf_get_tcam_entry_parms *parms __rte_unused)
540 int rc = -EOPNOTSUPP;
542 if (tfp == NULL || parms == NULL) {
543 PMD_DRV_LOG(ERR, "Invalid parameters\n");
547 if (tfp->session == NULL || tfp->session->core_data == NULL) {
549 "%s, Session info invalid\n",
550 tf_dir_2_str(parms->dir));
558 tf_free_tcam_entry(struct tf *tfp,
559 struct tf_free_tcam_entry_parms *parms)
562 struct tf_session *tfs;
563 struct bitalloc *session_pool;
565 if (parms == NULL || tfp == NULL)
568 if (tfp->session == NULL || tfp->session->core_data == NULL) {
569 PMD_DRV_LOG(ERR, "%s: Session error\n",
570 tf_dir_2_str(parms->dir));
574 tfs = (struct tf_session *)(tfp->session->core_data);
576 rc = tf_rm_lookup_tcam_type_pool(tfs,
578 parms->tcam_tbl_type,
580 /* Error logging handled by tf_rm_lookup_tcam_type_pool */
584 rc = ba_inuse(session_pool, (int)parms->idx);
585 if (rc == BA_FAIL || rc == BA_ENTRY_FREE) {
586 PMD_DRV_LOG(ERR, "%s: %s: Entry %d already free",
587 tf_dir_2_str(parms->dir),
588 tf_tcam_tbl_2_str(parms->tcam_tbl_type),
593 ba_free(session_pool, (int)parms->idx);
595 rc = tf_msg_tcam_entry_free(tfp, parms);
598 PMD_DRV_LOG(ERR, "%s: %s: Entry %d free failed",
599 tf_dir_2_str(parms->dir),
600 tf_tcam_tbl_2_str(parms->tcam_tbl_type),