]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(C) 2019 Marvell International Ltd. | |
3 | */ | |
4 | ||
5 | #include <rte_atomic.h> | |
6 | #include <rte_malloc.h> | |
7 | #include <rte_log.h> | |
8 | ||
9 | #include "otx2_common.h" | |
10 | #include "otx2_dev.h" | |
11 | #include "otx2_mbox.h" | |
12 | ||
13 | /** | |
14 | * @internal | |
15 | * Set default NPA configuration. | |
16 | */ | |
17 | void | |
18 | otx2_npa_set_defaults(struct otx2_idev_cfg *idev) | |
19 | { | |
20 | idev->npa_pf_func = 0; | |
21 | rte_atomic16_set(&idev->npa_refcnt, 0); | |
22 | } | |
23 | ||
24 | /** | |
25 | * @internal | |
26 | * Get intra device config structure. | |
27 | */ | |
28 | struct otx2_idev_cfg * | |
29 | otx2_intra_dev_get_cfg(void) | |
30 | { | |
31 | const char name[] = "octeontx2_intra_device_conf"; | |
32 | const struct rte_memzone *mz; | |
33 | struct otx2_idev_cfg *idev; | |
34 | ||
35 | mz = rte_memzone_lookup(name); | |
36 | if (mz != NULL) | |
37 | return mz->addr; | |
38 | ||
39 | /* Request for the first time */ | |
40 | mz = rte_memzone_reserve_aligned(name, sizeof(struct otx2_idev_cfg), | |
41 | SOCKET_ID_ANY, 0, OTX2_ALIGN); | |
42 | if (mz != NULL) { | |
43 | idev = mz->addr; | |
44 | idev->sso_pf_func = 0; | |
45 | idev->npa_lf = NULL; | |
46 | otx2_npa_set_defaults(idev); | |
47 | return idev; | |
48 | } | |
49 | return NULL; | |
50 | } | |
51 | ||
52 | /** | |
53 | * @internal | |
54 | * Get SSO PF_FUNC. | |
55 | */ | |
56 | uint16_t | |
57 | otx2_sso_pf_func_get(void) | |
58 | { | |
59 | struct otx2_idev_cfg *idev; | |
60 | uint16_t sso_pf_func; | |
61 | ||
62 | sso_pf_func = 0; | |
63 | idev = otx2_intra_dev_get_cfg(); | |
64 | ||
65 | if (idev != NULL) | |
66 | sso_pf_func = idev->sso_pf_func; | |
67 | ||
68 | return sso_pf_func; | |
69 | } | |
70 | ||
71 | /** | |
72 | * @internal | |
73 | * Set SSO PF_FUNC. | |
74 | */ | |
75 | void | |
76 | otx2_sso_pf_func_set(uint16_t sso_pf_func) | |
77 | { | |
78 | struct otx2_idev_cfg *idev; | |
79 | ||
80 | idev = otx2_intra_dev_get_cfg(); | |
81 | ||
82 | if (idev != NULL) { | |
83 | idev->sso_pf_func = sso_pf_func; | |
84 | rte_smp_wmb(); | |
85 | } | |
86 | } | |
87 | ||
88 | /** | |
89 | * @internal | |
90 | * Get NPA PF_FUNC. | |
91 | */ | |
92 | uint16_t | |
93 | otx2_npa_pf_func_get(void) | |
94 | { | |
95 | struct otx2_idev_cfg *idev; | |
96 | uint16_t npa_pf_func; | |
97 | ||
98 | npa_pf_func = 0; | |
99 | idev = otx2_intra_dev_get_cfg(); | |
100 | ||
101 | if (idev != NULL) | |
102 | npa_pf_func = idev->npa_pf_func; | |
103 | ||
104 | return npa_pf_func; | |
105 | } | |
106 | ||
107 | /** | |
108 | * @internal | |
109 | * Get NPA lf object. | |
110 | */ | |
111 | struct otx2_npa_lf * | |
112 | otx2_npa_lf_obj_get(void) | |
113 | { | |
114 | struct otx2_idev_cfg *idev; | |
115 | ||
116 | idev = otx2_intra_dev_get_cfg(); | |
117 | ||
118 | if (idev != NULL && rte_atomic16_read(&idev->npa_refcnt)) | |
119 | return idev->npa_lf; | |
120 | ||
121 | return NULL; | |
122 | } | |
123 | ||
124 | /** | |
125 | * @internal | |
126 | * Is NPA lf active for the given device?. | |
127 | */ | |
128 | int | |
129 | otx2_npa_lf_active(void *otx2_dev) | |
130 | { | |
131 | struct otx2_dev *dev = otx2_dev; | |
132 | struct otx2_idev_cfg *idev; | |
133 | ||
134 | /* Check if npalf is actively used on this dev */ | |
135 | idev = otx2_intra_dev_get_cfg(); | |
136 | if (!idev || !idev->npa_lf || idev->npa_lf->mbox != dev->mbox) | |
137 | return 0; | |
138 | ||
139 | return rte_atomic16_read(&idev->npa_refcnt); | |
140 | } | |
141 | ||
142 | /* | |
143 | * @internal | |
144 | * Gets reference only to existing NPA LF object. | |
145 | */ | |
146 | int otx2_npa_lf_obj_ref(void) | |
147 | { | |
148 | struct otx2_idev_cfg *idev; | |
149 | uint16_t cnt; | |
150 | int rc; | |
151 | ||
152 | idev = otx2_intra_dev_get_cfg(); | |
153 | ||
154 | /* Check if ref not possible */ | |
155 | if (idev == NULL) | |
156 | return -EINVAL; | |
157 | ||
158 | ||
159 | /* Get ref only if > 0 */ | |
160 | cnt = rte_atomic16_read(&idev->npa_refcnt); | |
161 | while (cnt != 0) { | |
162 | rc = rte_atomic16_cmpset(&idev->npa_refcnt_u16, cnt, cnt + 1); | |
163 | if (rc) | |
164 | break; | |
165 | ||
166 | cnt = rte_atomic16_read(&idev->npa_refcnt); | |
167 | } | |
168 | ||
169 | return cnt ? 0 : -EINVAL; | |
170 | } | |
171 | ||
172 | static int | |
173 | parse_npa_lock_mask(const char *key, const char *value, void *extra_args) | |
174 | { | |
175 | RTE_SET_USED(key); | |
176 | uint64_t val; | |
177 | ||
178 | val = strtoull(value, NULL, 16); | |
179 | ||
180 | *(uint64_t *)extra_args = val; | |
181 | ||
182 | return 0; | |
183 | } | |
184 | ||
185 | /* | |
186 | * @internal | |
187 | * Parse common device arguments | |
188 | */ | |
189 | void otx2_parse_common_devargs(struct rte_kvargs *kvlist) | |
190 | { | |
191 | ||
192 | struct otx2_idev_cfg *idev; | |
193 | uint64_t npa_lock_mask = 0; | |
194 | ||
195 | idev = otx2_intra_dev_get_cfg(); | |
196 | ||
197 | if (idev == NULL) | |
198 | return; | |
199 | ||
200 | rte_kvargs_process(kvlist, OTX2_NPA_LOCK_MASK, | |
201 | &parse_npa_lock_mask, &npa_lock_mask); | |
202 | ||
203 | idev->npa_lock_mask = npa_lock_mask; | |
204 | } | |
205 | ||
206 | /** | |
207 | * @internal | |
208 | */ | |
209 | int otx2_logtype_base; | |
210 | /** | |
211 | * @internal | |
212 | */ | |
213 | int otx2_logtype_mbox; | |
214 | /** | |
215 | * @internal | |
216 | */ | |
217 | int otx2_logtype_npa; | |
218 | /** | |
219 | * @internal | |
220 | */ | |
221 | int otx2_logtype_nix; | |
222 | /** | |
223 | * @internal | |
224 | */ | |
225 | int otx2_logtype_npc; | |
226 | /** | |
227 | * @internal | |
228 | */ | |
229 | int otx2_logtype_tm; | |
230 | /** | |
231 | * @internal | |
232 | */ | |
233 | int otx2_logtype_sso; | |
234 | /** | |
235 | * @internal | |
236 | */ | |
237 | int otx2_logtype_tim; | |
238 | /** | |
239 | * @internal | |
240 | */ | |
241 | int otx2_logtype_dpi; | |
242 | /** | |
243 | * @internal | |
244 | */ | |
245 | int otx2_logtype_ep; | |
246 | ||
247 | RTE_INIT(otx2_log_init); | |
248 | static void | |
249 | otx2_log_init(void) | |
250 | { | |
251 | otx2_logtype_base = rte_log_register("pmd.octeontx2.base"); | |
252 | if (otx2_logtype_base >= 0) | |
253 | rte_log_set_level(otx2_logtype_base, RTE_LOG_NOTICE); | |
254 | ||
255 | otx2_logtype_mbox = rte_log_register("pmd.octeontx2.mbox"); | |
256 | if (otx2_logtype_mbox >= 0) | |
257 | rte_log_set_level(otx2_logtype_mbox, RTE_LOG_NOTICE); | |
258 | ||
259 | otx2_logtype_npa = rte_log_register("pmd.mempool.octeontx2"); | |
260 | if (otx2_logtype_npa >= 0) | |
261 | rte_log_set_level(otx2_logtype_npa, RTE_LOG_NOTICE); | |
262 | ||
263 | otx2_logtype_nix = rte_log_register("pmd.net.octeontx2"); | |
264 | if (otx2_logtype_nix >= 0) | |
265 | rte_log_set_level(otx2_logtype_nix, RTE_LOG_NOTICE); | |
266 | ||
267 | otx2_logtype_npc = rte_log_register("pmd.net.octeontx2.flow"); | |
268 | if (otx2_logtype_npc >= 0) | |
269 | rte_log_set_level(otx2_logtype_npc, RTE_LOG_NOTICE); | |
270 | ||
271 | otx2_logtype_tm = rte_log_register("pmd.net.octeontx2.tm"); | |
272 | if (otx2_logtype_tm >= 0) | |
273 | rte_log_set_level(otx2_logtype_tm, RTE_LOG_NOTICE); | |
274 | ||
275 | otx2_logtype_sso = rte_log_register("pmd.event.octeontx2"); | |
276 | if (otx2_logtype_sso >= 0) | |
277 | rte_log_set_level(otx2_logtype_sso, RTE_LOG_NOTICE); | |
278 | ||
279 | otx2_logtype_tim = rte_log_register("pmd.event.octeontx2.timer"); | |
280 | if (otx2_logtype_tim >= 0) | |
281 | rte_log_set_level(otx2_logtype_tim, RTE_LOG_NOTICE); | |
282 | ||
283 | otx2_logtype_dpi = rte_log_register("pmd.raw.octeontx2.dpi"); | |
284 | if (otx2_logtype_dpi >= 0) | |
285 | rte_log_set_level(otx2_logtype_dpi, RTE_LOG_NOTICE); | |
286 | ||
287 | otx2_logtype_ep = rte_log_register("pmd.raw.octeontx2.ep"); | |
288 | if (otx2_logtype_ep >= 0) | |
289 | rte_log_set_level(otx2_logtype_ep, RTE_LOG_NOTICE); | |
290 | ||
291 | } |