1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019-2024 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <string.h> 7 #include <rte_common.h> 8 #include <rte_errno.h> 9 #include <rte_log.h> 10 11 #include "tf_core.h" 12 #include "tf_util.h" 13 #include "tf_common.h" 14 #include "tf_em.h" 15 #include "tf_msg.h" 16 #include "tfp.h" 17 #include "tf_ext_flow_handle.h" 18 #include "tf_device.h" 19 20 #include "bnxt.h" 21 22 /** 23 * EM Pool 24 */ 25 #include "dpool.h" 26 27 /** 28 * Insert EM internal entry API 29 * 30 * returns: 31 * 0 - Success 32 */ 33 int 34 tf_em_hash_insert_int_entry(struct tf *tfp, 35 struct tf_insert_em_entry_parms *parms) 36 { 37 int rc; 38 uint32_t gfid; 39 uint16_t rptr_index = 0; 40 uint8_t rptr_entry = 0; 41 uint8_t num_of_entries = 0; 42 struct dpool *pool; 43 uint32_t index; 44 uint32_t key0_hash; 45 uint32_t key1_hash; 46 uint64_t big_hash; 47 struct tf_dev_info *dev; 48 struct tf_session *tfs; 49 50 /* Retrieve the session information */ 51 rc = tf_session_get_session_internal(tfp, &tfs); 52 if (rc) 53 return rc; 54 55 /* Retrieve the device information */ 56 rc = tf_session_get_device(tfs, &dev); 57 if (rc) 58 return rc; 59 pool = (struct dpool *)tfs->em_pool[parms->dir]; 60 index = dpool_alloc(pool, 61 parms->em_record_sz_in_bits / 128, 62 DP_DEFRAG_TO_FIT); 63 64 if (index == DP_INVALID_INDEX) { 65 PMD_DRV_LOG_LINE(ERR, 66 "%s, EM entry index allocation failed", 67 tf_dir_2_str(parms->dir)); 68 return -ENOMEM; /* no more space to add entries */ 69 } 70 71 if (dev->ops->tf_dev_cfa_key_hash == NULL) 72 return -EINVAL; 73 74 big_hash = dev->ops->tf_dev_cfa_key_hash((uint64_t *)parms->key, 75 TF_P58_HW_EM_KEY_MAX_SIZE * 8); 76 key0_hash = (uint32_t)(big_hash >> 32); 77 key1_hash = (uint32_t)(big_hash & 0xFFFFFFFF); 78 79 rptr_index = index; 80 rc = tf_msg_hash_insert_em_internal_entry(tfp, 81 parms, 82 key0_hash, 83 key1_hash, 84 &rptr_index, 85 &rptr_entry, 86 &num_of_entries); 87 if (rc) { 88 /* Free the allocated index before returning */ 89 dpool_free(pool, index); 90 return rc; 91 } 92 93 TF_SET_GFID(gfid, 94 ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) | 95 rptr_entry), 96 0); /* N/A for internal table */ 97 98 TF_SET_FLOW_ID(parms->flow_id, 99 gfid, 100 TF_GFID_TABLE_INTERNAL, 101 parms->dir); 102 103 TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle, 104 (uint32_t)num_of_entries, 105 0, 106 TF_FLAGS_FLOW_HANDLE_INTERNAL, 107 rptr_index, 108 rptr_entry, 109 0); 110 dpool_set_entry_data(pool, index, parms->flow_handle); 111 112 #ifdef TF_FLOW_SCALE_QUERY 113 /* Update usage state buffer for EM */ 114 tf_em_usage_update(tfp, 115 parms->dir, 116 num_of_entries, 117 TF_RESC_ALLOC); 118 #endif /* TF_FLOW_SCALE_QUERY */ 119 120 return 0; 121 } 122 123 /** Delete EM internal entry API 124 * 125 * returns: 126 * 0 127 * -EINVAL 128 */ 129 int 130 tf_em_hash_delete_int_entry(struct tf *tfp, 131 struct tf_delete_em_entry_parms *parms) 132 { 133 int rc = 0; 134 struct tf_session *tfs; 135 struct dpool *pool; 136 #ifdef TF_FLOW_SCALE_QUERY 137 uint32_t size; 138 #endif /* TF_FLOW_SCALE_QUERY */ 139 140 /* Retrieve the session information */ 141 rc = tf_session_get_session(tfp, &tfs); 142 if (rc) { 143 TFP_DRV_LOG(ERR, 144 "%s: Failed to lookup session, rc:%s\n", 145 tf_dir_2_str(parms->dir), 146 strerror(-rc)); 147 return rc; 148 } 149 150 rc = tf_msg_delete_em_entry(tfp, parms); 151 152 /* Return resource to pool */ 153 pool = (struct dpool *)tfs->em_pool[parms->dir]; 154 155 #ifdef TF_FLOW_SCALE_QUERY 156 /* Update usage state buffer for EM */ 157 size = DP_FLAGS_SIZE(pool->entry[parms->index - pool->start_index].flags); 158 tf_em_usage_update(tfp, 159 parms->dir, 160 size, 161 TF_RESC_FREE); 162 #endif /* TF_FLOW_SCALE_QUERY */ 163 164 dpool_free(pool, parms->index); 165 return rc; 166 } 167 168 /** Move EM internal entry API 169 * 170 * returns: 171 * 0 172 * -EINVAL 173 */ 174 int 175 tf_em_move_int_entry(struct tf *tfp, 176 struct tf_move_em_entry_parms *parms) 177 { 178 int rc = 0; 179 struct dpool *pool; 180 struct tf_session *tfs; 181 182 /* Retrieve the session information */ 183 rc = tf_session_get_session(tfp, &tfs); 184 if (rc) { 185 TFP_DRV_LOG(ERR, 186 "%s: Failed to lookup session, rc:%s\n", 187 tf_dir_2_str(parms->dir), 188 strerror(-rc)); 189 return rc; 190 } 191 192 rc = tf_msg_move_em_entry(tfp, parms); 193 194 /* Return resource to pool */ 195 if (rc == 0) { 196 pool = (struct dpool *)tfs->em_pool[parms->dir]; 197 dpool_free(pool, parms->index); 198 } 199 200 return rc; 201 } 202