+
+int
+tf_close_session_new(struct tf *tfp)
+{
+ int rc;
+ struct tf_session_close_session_parms cparms = { 0 };
+ union tf_session_id session_id = { 0 };
+ uint8_t ref_count;
+
+ TF_CHECK_PARMS1(tfp);
+
+ cparms.ref_count = &ref_count;
+ cparms.session_id = &session_id;
+ rc = tf_session_close_session(tfp,
+ &cparms);
+ /* Logging handled by tf_session_close_session */
+ if (rc)
+ return rc;
+
+ TFP_DRV_LOG(INFO,
+ "Closed session, session_id:%d, ref_count:%d\n",
+ cparms.session_id->id,
+ *cparms.ref_count);
+
+ TFP_DRV_LOG(INFO,
+ "domain:%d, bus:%d, device:%d, fw_session_id:%d\n",
+ cparms.session_id->internal.domain,
+ cparms.session_id->internal.bus,
+ cparms.session_id->internal.device,
+ cparms.session_id->internal.fw_session_id);
+
+ return rc;
+}
+
+/** insert EM hash entry API
+ *
+ * returns:
+ * 0 - Success
+ * -EINVAL - Error
+ */
+int tf_insert_em_entry(struct tf *tfp,
+ struct tf_insert_em_entry_parms *parms)
+{
+ struct tf_session *tfs;
+ struct tf_dev_info *dev;
+ int rc;
+
+ TF_CHECK_PARMS_SESSION(tfp, parms);
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session(tfp, &tfs);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: Failed to lookup session, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return rc;
+ }
+
+ /* Retrieve the device information */
+ rc = tf_session_get_device(tfs, &dev);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: Failed to lookup device, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return rc;
+ }
+
+ rc = dev->ops->tf_dev_insert_em_entry(tfp, parms);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: EM insert failed, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return rc;
+ }
+
+ return -EINVAL;
+}
+
+/** Delete EM hash entry API
+ *
+ * returns:
+ * 0 - Success
+ * -EINVAL - Error
+ */
+int tf_delete_em_entry(struct tf *tfp,
+ struct tf_delete_em_entry_parms *parms)
+{
+ struct tf_session *tfs;
+ struct tf_dev_info *dev;
+ int rc;
+
+ TF_CHECK_PARMS_SESSION(tfp, parms);
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session(tfp, &tfs);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: Failed to lookup session, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return rc;
+ }
+
+ /* Retrieve the device information */
+ rc = tf_session_get_device(tfs, &dev);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: Failed to lookup device, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return rc;
+ }
+
+ rc = dev->ops->tf_dev_delete_em_entry(tfp, parms);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: EM delete failed, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return rc;
+ }
+
+ return rc;
+}
+
+int tf_alloc_identifier(struct tf *tfp,
+ struct tf_alloc_identifier_parms *parms)
+{
+ struct bitalloc *session_pool;
+ struct tf_session *tfs;
+ int id;
+ int rc;
+
+ TF_CHECK_PARMS_SESSION(tfp, parms);
+
+ tfs = (struct tf_session *)(tfp->session->core_data);
+
+ switch (parms->ident_type) {
+ case TF_IDENT_TYPE_L2_CTXT:
+ TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
+ TF_L2_CTXT_REMAP_POOL_NAME,
+ rc);
+ break;
+ case TF_IDENT_TYPE_PROF_FUNC:
+ TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
+ TF_PROF_FUNC_POOL_NAME,
+ rc);
+ break;
+ case TF_IDENT_TYPE_EM_PROF:
+ TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
+ TF_EM_PROF_ID_POOL_NAME,
+ rc);
+ break;
+ case TF_IDENT_TYPE_WC_PROF:
+ TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
+ TF_WC_TCAM_PROF_ID_POOL_NAME,
+ rc);
+ break;
+ case TF_IDENT_TYPE_L2_FUNC:
+ TFP_DRV_LOG(ERR, "%s: unsupported %s\n",
+ tf_dir_2_str(parms->dir),
+ tf_ident_2_str(parms->ident_type));
+ rc = -EOPNOTSUPP;
+ break;
+ default:
+ TFP_DRV_LOG(ERR, "%s: %s\n",
+ tf_dir_2_str(parms->dir),
+ tf_ident_2_str(parms->ident_type));
+ rc = -EOPNOTSUPP;
+ break;
+ }
+
+ if (rc) {
+ TFP_DRV_LOG(ERR, "%s: identifier pool %s failure, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ tf_ident_2_str(parms->ident_type),
+ strerror(-rc));
+ return rc;
+ }
+
+ id = ba_alloc(session_pool);
+
+ if (id == BA_FAIL) {
+ TFP_DRV_LOG(ERR, "%s: %s: No resource available\n",
+ tf_dir_2_str(parms->dir),
+ tf_ident_2_str(parms->ident_type));
+ return -ENOMEM;
+ }
+ parms->id = id;
+ return 0;
+}
+
+int
+tf_alloc_identifier_new(struct tf *tfp,
+ struct tf_alloc_identifier_parms *parms)
+{
+ int rc;
+ struct tf_session *tfs;
+ struct tf_dev_info *dev;
+ struct tf_ident_alloc_parms aparms;
+ uint16_t id;
+
+ TF_CHECK_PARMS2(tfp, parms);
+
+ /* Can't do static initialization due to UT enum check */
+ memset(&aparms, 0, sizeof(struct tf_ident_alloc_parms));
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session(tfp, &tfs);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: Failed to lookup session, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return rc;
+ }
+
+ /* Retrieve the device information */
+ rc = tf_session_get_device(tfs, &dev);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: Failed to lookup device, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return rc;
+ }
+
+ if (dev->ops->tf_dev_alloc_ident == NULL) {
+ rc = -EOPNOTSUPP;
+ TFP_DRV_LOG(ERR,
+ "%s: Operation not supported, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return -EOPNOTSUPP;
+ }
+
+ aparms.dir = parms->dir;
+ aparms.ident_type = parms->ident_type;
+ aparms.id = &id;
+ rc = dev->ops->tf_dev_alloc_ident(tfp, &aparms);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: Identifier allocation failed, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return rc;
+ }
+
+ parms->id = id;
+
+ return 0;
+}
+
+int tf_free_identifier(struct tf *tfp,
+ struct tf_free_identifier_parms *parms)
+{
+ struct bitalloc *session_pool;
+ int rc;
+ int ba_rc;
+ struct tf_session *tfs;
+
+ TF_CHECK_PARMS_SESSION(tfp, parms);
+
+ tfs = (struct tf_session *)(tfp->session->core_data);
+
+ switch (parms->ident_type) {
+ case TF_IDENT_TYPE_L2_CTXT:
+ TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
+ TF_L2_CTXT_REMAP_POOL_NAME,
+ rc);
+ break;
+ case TF_IDENT_TYPE_PROF_FUNC:
+ TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
+ TF_PROF_FUNC_POOL_NAME,
+ rc);
+ break;
+ case TF_IDENT_TYPE_EM_PROF:
+ TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
+ TF_EM_PROF_ID_POOL_NAME,
+ rc);
+ break;
+ case TF_IDENT_TYPE_WC_PROF:
+ TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
+ TF_WC_TCAM_PROF_ID_POOL_NAME,
+ rc);
+ break;
+ case TF_IDENT_TYPE_L2_FUNC:
+ TFP_DRV_LOG(ERR, "%s: unsupported %s\n",
+ tf_dir_2_str(parms->dir),
+ tf_ident_2_str(parms->ident_type));
+ rc = -EOPNOTSUPP;
+ break;
+ default:
+ TFP_DRV_LOG(ERR, "%s: invalid %s\n",
+ tf_dir_2_str(parms->dir),
+ tf_ident_2_str(parms->ident_type));
+ rc = -EOPNOTSUPP;
+ break;
+ }
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: %s Identifier pool access failed, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ tf_ident_2_str(parms->ident_type),
+ strerror(-rc));
+ return rc;
+ }
+
+ ba_rc = ba_inuse(session_pool, (int)parms->id);
+
+ if (ba_rc == BA_FAIL || ba_rc == BA_ENTRY_FREE) {
+ TFP_DRV_LOG(ERR, "%s: %s: Entry %d already free",
+ tf_dir_2_str(parms->dir),
+ tf_ident_2_str(parms->ident_type),
+ parms->id);
+ return -EINVAL;
+ }
+
+ ba_free(session_pool, (int)parms->id);
+
+ return 0;
+}
+
+int
+tf_free_identifier_new(struct tf *tfp,
+ struct tf_free_identifier_parms *parms)
+{
+ int rc;
+ struct tf_session *tfs;
+ struct tf_dev_info *dev;
+ struct tf_ident_free_parms fparms;
+
+ TF_CHECK_PARMS2(tfp, parms);
+
+ /* Can't do static initialization due to UT enum check */
+ memset(&fparms, 0, sizeof(struct tf_ident_free_parms));
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session(tfp, &tfs);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: Failed to lookup session, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return rc;
+ }
+
+ /* Retrieve the device information */
+ rc = tf_session_get_device(tfs, &dev);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: Failed to lookup device, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return rc;
+ }
+
+ if (dev->ops->tf_dev_free_ident == NULL) {
+ rc = -EOPNOTSUPP;
+ TFP_DRV_LOG(ERR,
+ "%s: Operation not supported, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return -EOPNOTSUPP;
+ }
+
+ fparms.dir = parms->dir;
+ fparms.ident_type = parms->ident_type;
+ fparms.id = parms->id;
+ rc = dev->ops->tf_dev_free_ident(tfp, &fparms);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: Identifier allocation failed, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ strerror(-rc));
+ return rc;
+ }
+
+ return 0;
+}
+
+int
+tf_alloc_tcam_entry(struct tf *tfp,
+ struct tf_alloc_tcam_entry_parms *parms)
+{
+ int rc;
+ int index;
+ struct tf_session *tfs;
+ struct bitalloc *session_pool;
+ uint16_t num_slice_per_row;
+
+ /* TEMP, due to device design. When tcam is modularized device
+ * should be retrieved from the session
+ */
+ enum tf_device_type device_type;
+ /* TEMP */
+ device_type = TF_DEVICE_TYPE_WH;
+
+ TF_CHECK_PARMS_SESSION(tfp, parms);
+
+ tfs = (struct tf_session *)(tfp->session->core_data);
+
+ rc = tf_check_tcam_entry(parms->tcam_tbl_type,
+ device_type,
+ parms->key_sz_in_bits,
+ &num_slice_per_row);
+ /* Error logging handled by tf_check_tcam_entry */
+ if (rc)
+ return rc;
+
+ rc = tf_rm_lookup_tcam_type_pool(tfs,
+ parms->dir,
+ parms->tcam_tbl_type,
+ &session_pool);
+ /* Error logging handled by tf_rm_lookup_tcam_type_pool */
+ if (rc)
+ return rc;
+
+ index = ba_alloc(session_pool);
+ if (index == BA_FAIL) {
+ TFP_DRV_LOG(ERR, "%s: %s: No resource available\n",
+ tf_dir_2_str(parms->dir),
+ tf_tcam_tbl_2_str(parms->tcam_tbl_type));
+ return -ENOMEM;
+ }
+
+ index *= num_slice_per_row;
+
+ parms->idx = index;
+ return 0;
+}
+
+int
+tf_set_tcam_entry(struct tf *tfp,
+ struct tf_set_tcam_entry_parms *parms)
+{
+ int rc;
+ int id;
+ int index;
+ struct tf_session *tfs;
+ struct bitalloc *session_pool;
+ uint16_t num_slice_per_row;
+
+ /* TEMP, due to device design. When tcam is modularized device
+ * should be retrieved from the session
+ */
+ enum tf_device_type device_type;
+ /* TEMP */
+ device_type = TF_DEVICE_TYPE_WH;
+
+ TF_CHECK_PARMS_SESSION(tfp, parms);
+
+ tfs = (struct tf_session *)(tfp->session->core_data);
+
+ rc = tf_check_tcam_entry(parms->tcam_tbl_type,
+ device_type,
+ parms->key_sz_in_bits,
+ &num_slice_per_row);
+ /* Error logging handled by tf_check_tcam_entry */
+ if (rc)
+ return rc;
+
+ rc = tf_rm_lookup_tcam_type_pool(tfs,
+ parms->dir,
+ parms->tcam_tbl_type,
+ &session_pool);
+ /* Error logging handled by tf_rm_lookup_tcam_type_pool */
+ if (rc)
+ return rc;
+
+ /* Verify that the entry has been previously allocated */
+ index = parms->idx / num_slice_per_row;
+
+ id = ba_inuse(session_pool, index);
+ if (id != 1) {
+ TFP_DRV_LOG(ERR,
+ "%s: %s: Invalid or not allocated index, idx:%d\n",
+ tf_dir_2_str(parms->dir),
+ tf_tcam_tbl_2_str(parms->tcam_tbl_type),
+ parms->idx);
+ return -EINVAL;
+ }
+
+ rc = tf_msg_tcam_entry_set(tfp, parms);
+
+ return rc;
+}
+
+int
+tf_get_tcam_entry(struct tf *tfp __rte_unused,
+ struct tf_get_tcam_entry_parms *parms __rte_unused)
+{
+ TF_CHECK_PARMS_SESSION(tfp, parms);
+ return -EOPNOTSUPP;
+}
+
+int
+tf_free_tcam_entry(struct tf *tfp,
+ struct tf_free_tcam_entry_parms *parms)
+{
+ int rc;
+ int index;
+ struct tf_session *tfs;
+ struct bitalloc *session_pool;
+ uint16_t num_slice_per_row = 1;
+
+ /* TEMP, due to device design. When tcam is modularized device
+ * should be retrieved from the session
+ */
+ enum tf_device_type device_type;
+ /* TEMP */
+ device_type = TF_DEVICE_TYPE_WH;
+
+ TF_CHECK_PARMS_SESSION(tfp, parms);
+ tfs = (struct tf_session *)(tfp->session->core_data);
+
+ rc = tf_check_tcam_entry(parms->tcam_tbl_type,
+ device_type,
+ 0,
+ &num_slice_per_row);
+ /* Error logging handled by tf_check_tcam_entry */
+ if (rc)
+ return rc;
+
+ rc = tf_rm_lookup_tcam_type_pool(tfs,
+ parms->dir,
+ parms->tcam_tbl_type,
+ &session_pool);
+ /* Error logging handled by tf_rm_lookup_tcam_type_pool */
+ if (rc)
+ return rc;
+
+ index = parms->idx / num_slice_per_row;
+
+ rc = ba_inuse(session_pool, index);
+ if (rc == BA_FAIL || rc == BA_ENTRY_FREE) {
+ TFP_DRV_LOG(ERR, "%s: %s: Entry %d already free",
+ tf_dir_2_str(parms->dir),
+ tf_tcam_tbl_2_str(parms->tcam_tbl_type),
+ index);
+ return -EINVAL;
+ }
+
+ ba_free(session_pool, index);
+
+ rc = tf_msg_tcam_entry_free(tfp, parms);
+ if (rc) {
+ /* Log error */
+ TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s",
+ tf_dir_2_str(parms->dir),
+ tf_tcam_tbl_2_str(parms->tcam_tbl_type),
+ parms->idx,
+ strerror(-rc));
+ }
+
+ return rc;
+}