1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2021 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
tf_em_hash_insert_int_entry(struct tf * tfp,struct tf_insert_em_entry_parms * parms)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(ERR,
66 "%s, EM entry index allocation failed\n",
67 tf_dir_2_str(parms->dir));
68 return -1;
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 -1;
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 return 0;
112 }
113
114 /** Delete EM internal entry API
115 *
116 * returns:
117 * 0
118 * -EINVAL
119 */
120 int
tf_em_hash_delete_int_entry(struct tf * tfp,struct tf_delete_em_entry_parms * parms)121 tf_em_hash_delete_int_entry(struct tf *tfp,
122 struct tf_delete_em_entry_parms *parms)
123 {
124 int rc = 0;
125 struct tf_session *tfs;
126 struct dpool *pool;
127 /* Retrieve the session information */
128 rc = tf_session_get_session(tfp, &tfs);
129 if (rc) {
130 TFP_DRV_LOG(ERR,
131 "%s: Failed to lookup session, rc:%s\n",
132 tf_dir_2_str(parms->dir),
133 strerror(-rc));
134 return rc;
135 }
136
137 rc = tf_msg_delete_em_entry(tfp, parms);
138
139 /* Return resource to pool */
140 if (rc == 0) {
141 pool = (struct dpool *)tfs->em_pool[parms->dir];
142 dpool_free(pool, parms->index);
143 }
144
145 return rc;
146 }
147
148 /** Move EM internal entry API
149 *
150 * returns:
151 * 0
152 * -EINVAL
153 */
154 int
tf_em_move_int_entry(struct tf * tfp,struct tf_move_em_entry_parms * parms)155 tf_em_move_int_entry(struct tf *tfp,
156 struct tf_move_em_entry_parms *parms)
157 {
158 int rc = 0;
159 struct dpool *pool;
160 struct tf_session *tfs;
161
162 /* Retrieve the session information */
163 rc = tf_session_get_session(tfp, &tfs);
164 if (rc) {
165 TFP_DRV_LOG(ERR,
166 "%s: Failed to lookup session, rc:%s\n",
167 tf_dir_2_str(parms->dir),
168 strerror(-rc));
169 return rc;
170 }
171
172 rc = tf_msg_move_em_entry(tfp, parms);
173
174 /* Return resource to pool */
175 if (rc == 0) {
176 pool = (struct dpool *)tfs->em_pool[parms->dir];
177 dpool_free(pool, parms->index);
178 }
179
180 return rc;
181 }
182