Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #ifndef _ROC_NPA_H_
6 : : #define _ROC_NPA_H_
7 : :
8 : : #include <stdint.h>
9 : :
10 : : #include "hw/npa.h"
11 : :
12 : : #include "roc_bits.h"
13 : : #include "roc_constants.h"
14 : : #if defined(__aarch64__)
15 : : #include "roc_io.h"
16 : : #else
17 : : #include "roc_io_generic.h"
18 : : #endif
19 : : #include "roc_npa_dp.h"
20 : :
21 : : #define ROC_AURA_OP_LIMIT_MASK (BIT_ULL(36) - 1)
22 : :
23 : : #define ROC_NPA_MAX_BLOCK_SZ (128 * 1024)
24 : : #define ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS 512
25 : : #define ROC_CN10K_NPA_BATCH_FREE_MAX_PTRS 15U
26 : : #define ROC_CN10K_NPA_BATCH_FREE_BURST_MAX 16U
27 : :
28 : : /* This value controls how much of the present average resource level is used to
29 : : * calculate the new resource level.
30 : : */
31 : : #define ROC_NPA_AVG_CONT 0xE0
32 : :
33 : : /* 16 CASP instructions can be outstanding in CN9k, but we use only 15
34 : : * outstanding CASPs as we run out of registers.
35 : : */
36 : : #define ROC_CN9K_NPA_BULK_ALLOC_MAX_PTRS 30
37 : :
38 : : /*
39 : : * Generate 64bit handle to have optimized alloc and free aura operation.
40 : : * 0 - ROC_AURA_ID_MASK for storing the aura_id.
41 : : * [ROC_AURA_ID_MASK+1, (2^64 - 1)] for storing the lf base address.
42 : : * This scheme is valid when OS can give ROC_AURA_ID_MASK
43 : : * aligned address for lf base address.
44 : : */
45 : : static inline uint64_t
46 : : roc_npa_aura_handle_gen(uint32_t aura_id, uintptr_t addr)
47 : : {
48 : : uint64_t val;
49 : :
50 : 0 : val = aura_id & ROC_AURA_ID_MASK;
51 [ # # # # ]: 0 : return (uint64_t)addr | val;
52 : : }
53 : :
54 : : static inline uint64_t
55 : : roc_npa_aura_op_alloc(uint64_t aura_handle, const int drop)
56 : : {
57 : : uint64_t wdata = roc_npa_aura_handle_to_aura(aura_handle);
58 : : int64_t *addr;
59 : :
60 : : if (drop)
61 : : wdata |= BIT_ULL(63); /* DROP */
62 : :
63 : : addr = (int64_t *)(roc_npa_aura_handle_to_base(aura_handle) +
64 : : NPA_LF_AURA_OP_ALLOCX(0));
65 : : return roc_atomic64_add_nosync(wdata, addr);
66 : : }
67 : :
68 : : static inline uint64_t
69 : : roc_npa_aura_op_cnt_get(uint64_t aura_handle)
70 : : {
71 : : uint64_t wdata;
72 : : int64_t *addr;
73 : : uint64_t reg;
74 : :
75 : : wdata = roc_npa_aura_handle_to_aura(aura_handle) << 44;
76 : : addr = (int64_t *)(roc_npa_aura_handle_to_base(aura_handle) +
77 : : NPA_LF_AURA_OP_CNT);
78 : : reg = roc_atomic64_add_nosync(wdata, addr);
79 : :
80 : : if (reg & BIT_ULL(42) /* OP_ERR */)
81 : : return 0;
82 : : else
83 : : return reg & 0xFFFFFFFFF;
84 : : }
85 : :
86 : : static inline void
87 : : roc_npa_aura_op_cnt_set(uint64_t aura_handle, const int sign, uint64_t count)
88 : : {
89 : : uint64_t reg = count & (BIT_ULL(36) - 1);
90 : :
91 : : if (sign)
92 : : reg |= BIT_ULL(43); /* CNT_ADD */
93 : :
94 : 0 : reg |= (roc_npa_aura_handle_to_aura(aura_handle) << 44);
95 : :
96 : 0 : plt_write64(reg, roc_npa_aura_handle_to_base(aura_handle) +
97 : : NPA_LF_AURA_OP_CNT);
98 : : }
99 : :
100 : : static inline uint64_t
101 : : roc_npa_aura_op_limit_get(uint64_t aura_handle)
102 : : {
103 : : uint64_t wdata;
104 : : int64_t *addr;
105 : : uint64_t reg;
106 : :
107 : : wdata = roc_npa_aura_handle_to_aura(aura_handle) << 44;
108 : : addr = (int64_t *)(roc_npa_aura_handle_to_base(aura_handle) +
109 : : NPA_LF_AURA_OP_LIMIT);
110 : : reg = roc_atomic64_add_nosync(wdata, addr);
111 : :
112 : : if (reg & BIT_ULL(42) /* OP_ERR */)
113 : : return 0;
114 : : else
115 : : return reg & ROC_AURA_OP_LIMIT_MASK;
116 : : }
117 : :
118 : : static inline void
119 : : roc_npa_aura_op_limit_set(uint64_t aura_handle, uint64_t limit)
120 : : {
121 : : uint64_t reg = limit & ROC_AURA_OP_LIMIT_MASK;
122 : :
123 : : reg |= (roc_npa_aura_handle_to_aura(aura_handle) << 44);
124 : :
125 : : plt_write64(reg, roc_npa_aura_handle_to_base(aura_handle) +
126 : : NPA_LF_AURA_OP_LIMIT);
127 : : }
128 : :
129 : : static inline uint64_t
130 : : roc_npa_aura_op_available(uint64_t aura_handle)
131 : : {
132 : : uint64_t wdata;
133 : : uint64_t reg;
134 : : int64_t *addr;
135 : :
136 : : wdata = roc_npa_aura_handle_to_aura(aura_handle) << 44;
137 : : addr = (int64_t *)(roc_npa_aura_handle_to_base(aura_handle) +
138 : : NPA_LF_POOL_OP_AVAILABLE);
139 : : reg = roc_atomic64_add_nosync(wdata, addr);
140 : :
141 : : if (reg & BIT_ULL(42) /* OP_ERR */)
142 : : return 0;
143 : : else
144 : : return reg & 0xFFFFFFFFF;
145 : : }
146 : :
147 : : /* Wait for a given timeout, repeatedly checking whether the available
148 : : * pointers has reached the given count. Returns the available pointer
149 : : * count if it has reached the given count or if timeout has expired
150 : : */
151 : : static inline uint32_t
152 : : roc_npa_aura_op_available_wait(uint64_t aura_handle, uint32_t count,
153 : : uint32_t tmo_ms)
154 : : {
155 : : #define OP_AVAIL_WAIT_MS_DEFAULT (100)
156 : : #define OP_AVAIL_CHECK_INTERVAL_MS (1)
157 : : uint32_t op_avail;
158 : : int retry;
159 : :
160 : : tmo_ms = tmo_ms ? tmo_ms : OP_AVAIL_WAIT_MS_DEFAULT;
161 : :
162 : : retry = tmo_ms / OP_AVAIL_CHECK_INTERVAL_MS;
163 : : op_avail = roc_npa_aura_op_available(aura_handle);
164 [ # # ]: 0 : while (retry && (op_avail < count)) {
165 : : plt_delay_ms(OP_AVAIL_CHECK_INTERVAL_MS);
166 : : op_avail = roc_npa_aura_op_available(aura_handle);
167 : 0 : retry--;
168 : : }
169 : :
170 : : return op_avail;
171 : : }
172 : :
173 : : static inline uint64_t
174 : : roc_npa_pool_op_performance_counter(uint64_t aura_handle, const int drop)
175 : : {
176 : : union {
177 : : uint64_t u;
178 : : struct npa_aura_op_wdata_s s;
179 : : } op_wdata;
180 : : int64_t *addr;
181 : : uint64_t reg;
182 : :
183 : : op_wdata.u = 0;
184 : : op_wdata.s.aura = roc_npa_aura_handle_to_aura(aura_handle);
185 : : if (drop)
186 : : op_wdata.s.drop |= BIT_ULL(63); /* DROP */
187 : :
188 : : addr = (int64_t *)(roc_npa_aura_handle_to_base(aura_handle) +
189 : : NPA_LF_POOL_OP_PC);
190 : :
191 : : reg = roc_atomic64_add_nosync(op_wdata.u, addr);
192 : : /*
193 : : * NPA_LF_POOL_OP_PC Read Data
194 : : *
195 : : * 63 49 48 48 47 0
196 : : * -----------------------------
197 : : * | Reserved | OP_ERR | OP_PC |
198 : : * -----------------------------
199 : : */
200 : :
201 : : if (reg & BIT_ULL(48) /* OP_ERR */)
202 : : return 0;
203 : : else
204 : : return reg & 0xFFFFFFFFFFFF;
205 : : }
206 : :
207 : : static inline int
208 : : roc_npa_aura_batch_alloc_issue(uint64_t aura_handle, uint64_t *buf,
209 : : unsigned int num, const int dis_wait,
210 : : const int drop)
211 : : {
212 : : int64_t *addr;
213 : : uint64_t res;
214 : : union {
215 : : uint64_t u;
216 : : struct npa_batch_alloc_compare_s compare_s;
217 : : } cmp;
218 : :
219 [ # # # # : 0 : if (num > ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS)
# # ]
220 : : return -1;
221 : :
222 : : addr = (int64_t *)(roc_npa_aura_handle_to_base(aura_handle) +
223 : : NPA_LF_AURA_BATCH_ALLOC);
224 [ # # # # ]: 0 : cmp.u = 0;
225 : 0 : cmp.compare_s.aura = roc_npa_aura_handle_to_aura(aura_handle);
226 : 0 : cmp.compare_s.drop = drop;
227 : : cmp.compare_s.stype = ALLOC_STYPE_STF;
228 : : cmp.compare_s.dis_wait = dis_wait;
229 : 0 : cmp.compare_s.count = num;
230 : :
231 : 0 : res = roc_atomic64_casl(cmp.u, (uint64_t)buf, addr);
232 [ # # # # : 0 : if (res != ALLOC_RESULT_ACCEPTED && res != ALLOC_RESULT_NOCORE)
# # ]
233 : 0 : return -1;
234 : :
235 : : return 0;
236 : : }
237 : :
238 : : /*
239 : : * Wait for a batch alloc operation on a cache line to complete.
240 : : */
241 : : static inline void
242 : 0 : roc_npa_batch_alloc_wait(uint64_t *cache_line, unsigned int wait_us)
243 : : {
244 : 0 : const uint64_t ticks = (uint64_t)wait_us * plt_tsc_hz() / (uint64_t)1E6;
245 : : const uint64_t start = plt_tsc_cycles();
246 : :
247 : : /* Batch alloc status code is updated in bits [5:6] of the first word
248 : : * of the 128 byte cache line.
249 : : */
250 [ # # ]: 0 : while (((__atomic_load_n(cache_line, __ATOMIC_RELAXED) >> 5) & 0x3) ==
251 : : ALLOC_CCODE_INVAL)
252 [ # # # # ]: 0 : if (wait_us && (plt_tsc_cycles() - start) >= ticks)
253 : : break;
254 : 0 : }
255 : :
256 : : /*
257 : : * Count the number of pointers in a single batch alloc cache line.
258 : : */
259 : : static inline unsigned int
260 : : roc_npa_aura_batch_alloc_count_line(uint64_t *line, unsigned int wait_us)
261 : : {
262 : : struct npa_batch_alloc_status_s *status;
263 : :
264 : : status = (struct npa_batch_alloc_status_s *)line;
265 : : roc_npa_batch_alloc_wait(line, wait_us);
266 : :
267 : : return status->count;
268 : : }
269 : :
270 : : /*
271 : : * Count the number of pointers in a sequence of batch alloc cache lines.
272 : : */
273 : : static inline unsigned int
274 : : roc_npa_aura_batch_alloc_count(uint64_t *aligned_buf, unsigned int num,
275 : : unsigned int wait_us)
276 : : {
277 : : unsigned int count, i;
278 : :
279 [ # # ]: 0 : if (num > ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS)
280 : : return 0;
281 : :
282 : : count = 0;
283 : : /* Check each ROC cache line one by one */
284 [ # # ]: 0 : for (i = 0; i < num; i += (ROC_ALIGN >> 3)) {
285 : : struct npa_batch_alloc_status_s *status;
286 : :
287 : 0 : status = (struct npa_batch_alloc_status_s *)&aligned_buf[i];
288 : :
289 : 0 : roc_npa_batch_alloc_wait(&aligned_buf[i], wait_us);
290 : :
291 : 0 : count += status->count;
292 : : }
293 : :
294 : : return count;
295 : : }
296 : :
297 : : /*
298 : : * Extract allocated pointers from a single batch alloc cache line. This api
299 : : * only extracts the required number of pointers from the cache line and it
300 : : * adjusts the statsus->count so that a subsequent call to this api can
301 : : * extract the remaining pointers in the cache line appropriately.
302 : : */
303 : : static inline unsigned int
304 : : roc_npa_aura_batch_alloc_extract_line(uint64_t *buf, uint64_t *line,
305 : : unsigned int num, unsigned int *rem)
306 : : {
307 : : struct npa_batch_alloc_status_s *status;
308 : : unsigned int avail;
309 : :
310 : : status = (struct npa_batch_alloc_status_s *)line;
311 : : roc_npa_batch_alloc_wait(line, 0);
312 : : avail = status->count;
313 : : num = avail > num ? num : avail;
314 : : if (num)
315 : : memcpy(buf, &line[avail - num], num * sizeof(uint64_t));
316 : : avail -= num;
317 : : if (avail == 0) {
318 : : /* Clear the lowest 7 bits of the first pointer */
319 : : buf[0] &= ~0x7FUL;
320 : : status->ccode = 0;
321 : : }
322 : : status->count = avail;
323 : : *rem = avail;
324 : :
325 : : return num;
326 : : }
327 : :
328 : : /*
329 : : * Extract all allocated pointers from a sequence of batch alloc cache lines.
330 : : */
331 : : static inline unsigned int
332 : 0 : roc_npa_aura_batch_alloc_extract(uint64_t *buf, uint64_t *aligned_buf,
333 : : unsigned int num)
334 : : {
335 : : unsigned int count, i;
336 : :
337 [ # # ]: 0 : if (num > ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS)
338 : : return 0;
339 : :
340 : : count = 0;
341 : : /* Check each ROC cache line one by one */
342 [ # # ]: 0 : for (i = 0; i < num; i += (ROC_ALIGN >> 3)) {
343 : : struct npa_batch_alloc_status_s *status;
344 : : int line_count;
345 : :
346 : 0 : status = (struct npa_batch_alloc_status_s *)&aligned_buf[i];
347 : :
348 : 0 : roc_npa_batch_alloc_wait(&aligned_buf[i], 0);
349 : :
350 : 0 : line_count = status->count;
351 : :
352 : : /* Clear the status from the cache line */
353 : 0 : status->ccode = 0;
354 : 0 : status->count = 0;
355 : :
356 : : /* 'Compress' the allocated buffers as there can
357 : : * be 'holes' at the end of the 128 byte cache
358 : : * lines.
359 : : */
360 : 0 : memmove(&buf[count], &aligned_buf[i],
361 : : line_count * sizeof(uint64_t));
362 : :
363 : 0 : count += line_count;
364 : : }
365 : :
366 : : return count;
367 : : }
368 : :
369 : : static inline void
370 : : roc_npa_aura_op_bulk_free(uint64_t aura_handle, uint64_t const *buf,
371 : : unsigned int num, const int fabs)
372 : : {
373 : : unsigned int i;
374 : :
375 [ # # ]: 0 : for (i = 0; i < num; i++) {
376 : 0 : const uint64_t inbuf = buf[i];
377 : :
378 : : roc_npa_aura_op_free(aura_handle, fabs, inbuf);
379 : : }
380 : : }
381 : :
382 : : /*
383 : : * Issue a batch alloc operation on a sequence of cache lines, wait for the
384 : : * batch alloc to complete and copy the pointers out into the user buffer.
385 : : */
386 : : static inline unsigned int
387 : : roc_npa_aura_op_batch_alloc(uint64_t aura_handle, uint64_t *buf,
388 : : unsigned int num, uint64_t *aligned_buf,
389 : : unsigned int aligned_buf_sz, const int dis_wait,
390 : : const int drop, const int partial)
391 : : {
392 : : unsigned int count, chunk, num_alloc;
393 : :
394 : : /* The buffer should be 128 byte cache line aligned */
395 : : if (((uint64_t)aligned_buf & (ROC_ALIGN - 1)) != 0)
396 : : return 0;
397 : :
398 : : count = 0;
399 : : while (num) {
400 : : /* Make sure that the pointers allocated fit into the cache
401 : : * lines reserved.
402 : : */
403 : : chunk = aligned_buf_sz / sizeof(uint64_t);
404 : : chunk = PLT_MIN(num, chunk);
405 : : chunk = PLT_MIN((int)chunk, ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS);
406 : :
407 : : if (roc_npa_aura_batch_alloc_issue(aura_handle, aligned_buf,
408 : : chunk, dis_wait, drop))
409 : : break;
410 : :
411 : : num_alloc = roc_npa_aura_batch_alloc_extract(buf, aligned_buf,
412 : : chunk);
413 : :
414 : : count += num_alloc;
415 : : buf += num_alloc;
416 : : num -= num_alloc;
417 : :
418 : : if (num_alloc != chunk)
419 : : break;
420 : : }
421 : :
422 : : /* If the requested number of pointers was not allocated and if partial
423 : : * alloc is not desired, then free allocated pointers.
424 : : */
425 : : if (unlikely(num != 0 && !partial)) {
426 : : roc_npa_aura_op_bulk_free(aura_handle, buf - count, count, 1);
427 : : count = 0;
428 : : }
429 : :
430 : : return count;
431 : : }
432 : :
433 : : static inline void
434 : : roc_npa_aura_batch_free(uint64_t aura_handle, uint64_t const *buf,
435 : : unsigned int num, const int fabs, uint64_t lmt_addr,
436 : : uint64_t lmt_id)
437 : : {
438 : : uint64_t addr, tar_addr, free0;
439 : : volatile uint64_t *lmt_data;
440 : : unsigned int i;
441 : :
442 [ # # ]: 0 : lmt_data = (uint64_t *)lmt_addr;
443 : :
444 : : addr = roc_npa_aura_handle_to_base(aura_handle) +
445 : : NPA_LF_AURA_BATCH_FREE0;
446 : :
447 : : /*
448 : : * NPA_LF_AURA_BATCH_FREE0
449 : : *
450 : : * 63 63 62 33 32 32 31 20 19 0
451 : : * -----------------------------------------
452 : : * | FABS | Rsvd | COUNT_EOT | Rsvd | AURA |
453 : : * -----------------------------------------
454 : : */
455 : : free0 = roc_npa_aura_handle_to_aura(aura_handle);
456 [ # # ]: 0 : free0 |= ((uint64_t)!!fabs << 63);
457 : 0 : free0 |= ((uint64_t)(num & 0x1) << 32);
458 : :
459 : : /* tar_addr[4:6] is LMTST size-1 in units of 128b */
460 : : tar_addr = addr | ((num >> 1) << 4);
461 : :
462 : 0 : lmt_data[0] = free0;
463 [ # # ]: 0 : for (i = 0; i < num; i++)
464 : 0 : lmt_data[i + 1] = buf[i];
465 : :
466 : : roc_lmt_submit_steorl(lmt_id, tar_addr);
467 : 0 : plt_io_wmb();
468 : 0 : }
469 : :
470 : : static inline void
471 [ # # ]: 0 : roc_npa_aura_batch_free_burst(uint64_t aura_handle, uint64_t const *buf,
472 : : unsigned int num, const int fabs,
473 : : uint64_t lmt_addr, uint64_t lmt_id)
474 : : {
475 : : uint64_t addr, tar_addr, free0, send_data, lmtline;
476 : : uint64_t *lmt_data;
477 : :
478 : : /* 63 52 51 20 19 7 6 4 3 0
479 : : * ----------------------------------------
480 : : * | RSVD | ADDR | RSVD | LMTST SZ(0) | 0 |
481 : : * ----------------------------------------
482 : : */
483 : : addr = roc_npa_aura_handle_to_base(aura_handle) +
484 : : NPA_LF_AURA_BATCH_FREE0;
485 : : tar_addr = addr | (0x7 << 4);
486 : :
487 : : /* 63 63 62 33 32 32 31 20 19 0
488 : : * -----------------------------------------
489 : : * | FABS | Rsvd | COUNT_EOT | Rsvd | AURA |
490 : : * -----------------------------------------
491 : : */
492 : : free0 = roc_npa_aura_handle_to_aura(aura_handle);
493 [ # # ]: 0 : free0 |= ((uint64_t)!!fabs << 63);
494 : 0 : free0 |= (0x1UL << 32);
495 : :
496 : : /* Fill the lmt lines */
497 : 0 : lmt_data = (uint64_t *)lmt_addr;
498 : : lmtline = 0;
499 [ # # ]: 0 : while (num) {
500 : 0 : lmt_data[lmtline * 16] = free0;
501 : 0 : memcpy(&lmt_data[(lmtline * 16) + 1], buf,
502 : : ROC_CN10K_NPA_BATCH_FREE_MAX_PTRS * sizeof(uint64_t));
503 : 0 : lmtline++;
504 : 0 : num -= ROC_CN10K_NPA_BATCH_FREE_MAX_PTRS;
505 : 0 : buf += ROC_CN10K_NPA_BATCH_FREE_MAX_PTRS;
506 : : }
507 : :
508 : : /* 63 19 18 16 15 12 11 11 10 0
509 : : * ---------------------------------------------------------------
510 : : * | LMTST SZ(15) ... LMTST SZ(1) | Rsvd | CNTM1 | Rsvd | LMT_ID |
511 : : * ---------------------------------------------------------------
512 : : */
513 : : send_data = lmt_id | ((lmtline - 1) << 12) | (0x1FFFFFFFFFFFUL << 19);
514 : : roc_lmt_submit_steorl(send_data, tar_addr);
515 : 0 : plt_io_wmb();
516 : 0 : }
517 : :
518 : : static inline void
519 : 0 : roc_npa_aura_op_batch_free(uint64_t aura_handle, uint64_t const *buf,
520 : : unsigned int num, const int fabs, uint64_t lmt_addr,
521 : : uint64_t lmt_id)
522 : : {
523 : : unsigned int max_burst, chunk, bnum;
524 : :
525 : : max_burst = ROC_CN10K_NPA_BATCH_FREE_MAX_PTRS *
526 : : ROC_CN10K_NPA_BATCH_FREE_BURST_MAX;
527 : 0 : bnum = num / ROC_CN10K_NPA_BATCH_FREE_MAX_PTRS;
528 : 0 : bnum *= ROC_CN10K_NPA_BATCH_FREE_MAX_PTRS;
529 : : num -= bnum;
530 : :
531 [ # # ]: 0 : while (bnum) {
532 : 0 : chunk = (bnum >= max_burst) ? max_burst : bnum;
533 : 0 : roc_npa_aura_batch_free_burst(aura_handle, buf, chunk, fabs,
534 : : lmt_addr, lmt_id);
535 : 0 : buf += chunk;
536 : 0 : bnum -= chunk;
537 : : }
538 : :
539 [ # # ]: 0 : if (num)
540 : : roc_npa_aura_batch_free(aura_handle, buf, num, fabs, lmt_addr,
541 : : lmt_id);
542 : 0 : }
543 : :
544 : : static inline unsigned int
545 : : roc_npa_aura_bulk_alloc(uint64_t aura_handle, uint64_t *buf, unsigned int num,
546 : : const int drop)
547 : : {
548 : : #if defined(__aarch64__)
549 : : uint64_t wdata = roc_npa_aura_handle_to_aura(aura_handle);
550 : : unsigned int i, count;
551 : : uint64_t addr;
552 : :
553 : : if (drop)
554 : : wdata |= BIT_ULL(63); /* DROP */
555 : :
556 : : addr = roc_npa_aura_handle_to_base(aura_handle) +
557 : : NPA_LF_AURA_OP_ALLOCX(0);
558 : :
559 : : switch (num) {
560 : : case 30:
561 : : asm volatile(
562 : : ".arch_extension lse\n"
563 : : "mov v18.d[0], %[dst]\n"
564 : : "mov v18.d[1], %[loc]\n"
565 : : "mov v19.d[0], %[wdata]\n"
566 : : "mov v19.d[1], x30\n"
567 : : "mov v20.d[0], x24\n"
568 : : "mov v20.d[1], x25\n"
569 : : "mov v21.d[0], x26\n"
570 : : "mov v21.d[1], x27\n"
571 : : "mov v22.d[0], x28\n"
572 : : "mov v22.d[1], x29\n"
573 : : "mov x28, v19.d[0]\n"
574 : : "mov x29, v19.d[0]\n"
575 : : "mov x30, v18.d[1]\n"
576 : : "casp x0, x1, x28, x29, [x30]\n"
577 : : "casp x2, x3, x28, x29, [x30]\n"
578 : : "casp x4, x5, x28, x29, [x30]\n"
579 : : "casp x6, x7, x28, x29, [x30]\n"
580 : : "casp x8, x9, x28, x29, [x30]\n"
581 : : "casp x10, x11, x28, x29, [x30]\n"
582 : : "casp x12, x13, x28, x29, [x30]\n"
583 : : "casp x14, x15, x28, x29, [x30]\n"
584 : : "casp x16, x17, x28, x29, [x30]\n"
585 : : "casp x18, x19, x28, x29, [x30]\n"
586 : : "casp x20, x21, x28, x29, [x30]\n"
587 : : "casp x22, x23, x28, x29, [x30]\n"
588 : : "casp x24, x25, x28, x29, [x30]\n"
589 : : "casp x26, x27, x28, x29, [x30]\n"
590 : : "casp x28, x29, x28, x29, [x30]\n"
591 : : "mov x30, v18.d[0]\n"
592 : : "stp x0, x1, [x30]\n"
593 : : "stp x2, x3, [x30, #16]\n"
594 : : "stp x4, x5, [x30, #32]\n"
595 : : "stp x6, x7, [x30, #48]\n"
596 : : "stp x8, x9, [x30, #64]\n"
597 : : "stp x10, x11, [x30, #80]\n"
598 : : "stp x12, x13, [x30, #96]\n"
599 : : "stp x14, x15, [x30, #112]\n"
600 : : "stp x16, x17, [x30, #128]\n"
601 : : "stp x18, x19, [x30, #144]\n"
602 : : "stp x20, x21, [x30, #160]\n"
603 : : "stp x22, x23, [x30, #176]\n"
604 : : "stp x24, x25, [x30, #192]\n"
605 : : "stp x26, x27, [x30, #208]\n"
606 : : "stp x28, x29, [x30, #224]\n"
607 : : "mov %[dst], v18.d[0]\n"
608 : : "mov %[loc], v18.d[1]\n"
609 : : "mov %[wdata], v19.d[0]\n"
610 : : "mov x30, v19.d[1]\n"
611 : : "mov x24, v20.d[0]\n"
612 : : "mov x25, v20.d[1]\n"
613 : : "mov x26, v21.d[0]\n"
614 : : "mov x27, v21.d[1]\n"
615 : : "mov x28, v22.d[0]\n"
616 : : "mov x29, v22.d[1]\n"
617 : : :
618 : : : [wdata] "r"(wdata), [loc] "r"(addr), [dst] "r"(buf)
619 : : : "memory", "x0", "x1", "x2", "x3", "x4", "x5", "x6",
620 : : "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14",
621 : : "x15", "x16", "x17", "x18", "x19", "x20", "x21",
622 : : "x22", "x23", "v18", "v19", "v20", "v21", "v22");
623 : : break;
624 : : case 16:
625 : : asm volatile(
626 : : ".arch_extension lse\n"
627 : : "mov x16, %[wdata]\n"
628 : : "mov x17, %[wdata]\n"
629 : : "casp x0, x1, x16, x17, [%[loc]]\n"
630 : : "casp x2, x3, x16, x17, [%[loc]]\n"
631 : : "casp x4, x5, x16, x17, [%[loc]]\n"
632 : : "casp x6, x7, x16, x17, [%[loc]]\n"
633 : : "casp x8, x9, x16, x17, [%[loc]]\n"
634 : : "casp x10, x11, x16, x17, [%[loc]]\n"
635 : : "casp x12, x13, x16, x17, [%[loc]]\n"
636 : : "casp x14, x15, x16, x17, [%[loc]]\n"
637 : : "stp x0, x1, [%[dst]]\n"
638 : : "stp x2, x3, [%[dst], #16]\n"
639 : : "stp x4, x5, [%[dst], #32]\n"
640 : : "stp x6, x7, [%[dst], #48]\n"
641 : : "stp x8, x9, [%[dst], #64]\n"
642 : : "stp x10, x11, [%[dst], #80]\n"
643 : : "stp x12, x13, [%[dst], #96]\n"
644 : : "stp x14, x15, [%[dst], #112]\n"
645 : : :
646 : : : [wdata] "r"(wdata), [dst] "r"(buf), [loc] "r"(addr)
647 : : : "memory", "x0", "x1", "x2", "x3", "x4", "x5", "x6",
648 : : "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14",
649 : : "x15", "x16", "x17");
650 : : break;
651 : : case 8:
652 : : asm volatile(
653 : : ".arch_extension lse\n"
654 : : "mov x16, %[wdata]\n"
655 : : "mov x17, %[wdata]\n"
656 : : "casp x0, x1, x16, x17, [%[loc]]\n"
657 : : "casp x2, x3, x16, x17, [%[loc]]\n"
658 : : "casp x4, x5, x16, x17, [%[loc]]\n"
659 : : "casp x6, x7, x16, x17, [%[loc]]\n"
660 : : "stp x0, x1, [%[dst]]\n"
661 : : "stp x2, x3, [%[dst], #16]\n"
662 : : "stp x4, x5, [%[dst], #32]\n"
663 : : "stp x6, x7, [%[dst], #48]\n"
664 : : :
665 : : : [wdata] "r"(wdata), [dst] "r"(buf), [loc] "r"(addr)
666 : : : "memory", "x0", "x1", "x2", "x3", "x4", "x5", "x6",
667 : : "x7", "x16", "x17");
668 : : break;
669 : : case 4:
670 : : asm volatile(
671 : : ".arch_extension lse\n"
672 : : "mov x16, %[wdata]\n"
673 : : "mov x17, %[wdata]\n"
674 : : "casp x0, x1, x16, x17, [%[loc]]\n"
675 : : "casp x2, x3, x16, x17, [%[loc]]\n"
676 : : "stp x0, x1, [%[dst]]\n"
677 : : "stp x2, x3, [%[dst], #16]\n"
678 : : :
679 : : : [wdata] "r"(wdata), [dst] "r"(buf), [loc] "r"(addr)
680 : : : "memory", "x0", "x1", "x2", "x3", "x16", "x17");
681 : : break;
682 : : case 2:
683 : : asm volatile(
684 : : ".arch_extension lse\n"
685 : : "mov x16, %[wdata]\n"
686 : : "mov x17, %[wdata]\n"
687 : : "casp x0, x1, x16, x17, [%[loc]]\n"
688 : : "stp x0, x1, [%[dst]]\n"
689 : : :
690 : : : [wdata] "r"(wdata), [dst] "r"(buf), [loc] "r"(addr)
691 : : : "memory", "x0", "x1", "x16", "x17");
692 : : break;
693 : : case 1:
694 : : buf[0] = roc_npa_aura_op_alloc(aura_handle, drop);
695 : : return !!buf[0];
696 : : }
697 : :
698 : : /* Pack the pointers */
699 : : for (i = 0, count = 0; i < num; i++)
700 : : if (buf[i])
701 : : buf[count++] = buf[i];
702 : :
703 : : return count;
704 : : #else
705 : : unsigned int i, count;
706 : :
707 [ # # ]: 0 : for (i = 0, count = 0; i < num; i++) {
708 : 0 : buf[count] = roc_npa_aura_op_alloc(aura_handle, drop);
709 : : if (buf[count])
710 : : count++;
711 : : }
712 : :
713 : : return count;
714 : : #endif
715 : : }
716 : :
717 : : static inline unsigned int
718 : : roc_npa_aura_op_bulk_alloc(uint64_t aura_handle, uint64_t *buf,
719 : : unsigned int num, const int drop, const int partial)
720 : : {
721 : : unsigned int chunk, count, num_alloc;
722 : :
723 : : count = 0;
724 [ # # ]: 0 : while (num) {
725 : : chunk = (num >= ROC_CN9K_NPA_BULK_ALLOC_MAX_PTRS) ?
726 [ # # ]: 0 : ROC_CN9K_NPA_BULK_ALLOC_MAX_PTRS :
727 : : plt_align32prevpow2(num);
728 : :
729 : : num_alloc =
730 : : roc_npa_aura_bulk_alloc(aura_handle, buf, chunk, drop);
731 : :
732 : : count += num_alloc;
733 : : buf += num_alloc;
734 : : num -= num_alloc;
735 : :
736 [ # # ]: 0 : if (unlikely(num_alloc != chunk))
737 : : break;
738 : : }
739 : :
740 : : /* If the requested number of pointers was not allocated and if partial
741 : : * alloc is not desired, then free allocated pointers.
742 : : */
743 : : if (unlikely(num != 0 && !partial)) {
744 : : roc_npa_aura_op_bulk_free(aura_handle, buf - count, count, 1);
745 : : count = 0;
746 : : }
747 : :
748 : : return count;
749 : : }
750 : :
751 : : struct roc_npa {
752 : : struct plt_pci_device *pci_dev;
753 : :
754 : : #define ROC_NPA_MEM_SZ (1 * 1024)
755 : : uint8_t reserved[ROC_NPA_MEM_SZ] __plt_cache_aligned;
756 : : } __plt_cache_aligned;
757 : :
758 : : int __roc_api roc_npa_dev_init(struct roc_npa *roc_npa);
759 : : int __roc_api roc_npa_dev_fini(struct roc_npa *roc_npa);
760 : :
761 : : /* Flags to pool create */
762 : : #define ROC_NPA_ZERO_AURA_F BIT(0)
763 : :
764 : : /* Enumerations */
765 : : enum roc_npa_buf_type {
766 : : /* Aura used for normal pkts */
767 : : ROC_NPA_BUF_TYPE_PACKET = 0,
768 : : /* Aura used for ipsec pkts */
769 : : ROC_NPA_BUF_TYPE_PACKET_IPSEC,
770 : : /* Aura used as vwqe for normal pkts */
771 : : ROC_NPA_BUF_TYPE_VWQE,
772 : : /* Aura used as vwqe for ipsec pkts */
773 : : ROC_NPA_BUF_TYPE_VWQE_IPSEC,
774 : : /* Aura used as SQB for SQ */
775 : : ROC_NPA_BUF_TYPE_SQB,
776 : : /* Aura used for general buffer */
777 : : ROC_NPA_BUF_TYPE_BUF,
778 : : /* Aura used for timeout pool */
779 : : ROC_NPA_BUF_TYPE_TIMEOUT,
780 : : ROC_NPA_BUF_TYPE_END,
781 : : };
782 : :
783 : : /* NPA pool */
784 : : int __roc_api roc_npa_pool_create(uint64_t *aura_handle, uint32_t block_size,
785 : : uint32_t block_count, struct npa_aura_s *aura,
786 : : struct npa_pool_s *pool, uint32_t flags);
787 : : int __roc_api roc_npa_aura_limit_modify(uint64_t aura_handle,
788 : : uint16_t aura_limit);
789 : : int __roc_api roc_npa_pool_destroy(uint64_t aura_handle);
790 : : int __roc_api roc_npa_pool_range_update_check(uint64_t aura_handle);
791 : : void __roc_api roc_npa_aura_op_range_set(uint64_t aura_handle,
792 : : uint64_t start_iova,
793 : : uint64_t end_iova);
794 : : void __roc_api roc_npa_aura_op_range_get(uint64_t aura_handle,
795 : : uint64_t *start_iova,
796 : : uint64_t *end_iova);
797 : : void __roc_api roc_npa_pool_op_range_set(uint64_t aura_handle,
798 : : uint64_t start_iova,
799 : : uint64_t end_iova);
800 : : int __roc_api roc_npa_aura_create(uint64_t *aura_handle, uint32_t block_count,
801 : : struct npa_aura_s *aura, int pool_id,
802 : : uint32_t flags);
803 : : int __roc_api roc_npa_aura_destroy(uint64_t aura_handle);
804 : : uint64_t __roc_api roc_npa_zero_aura_handle(void);
805 : : int __roc_api roc_npa_buf_type_update(uint64_t aura_handle, enum roc_npa_buf_type type, int cnt);
806 : : uint64_t __roc_api roc_npa_buf_type_mask(uint64_t aura_handle);
807 : : uint64_t __roc_api roc_npa_buf_type_limit_get(uint64_t type_mask);
808 : : int __roc_api roc_npa_aura_bp_configure(uint64_t aura_id, uint16_t bpid, uint8_t bp_intf,
809 : : uint8_t bp_thresh, bool enable);
810 : :
811 : : /* Init callbacks */
812 : : typedef int (*roc_npa_lf_init_cb_t)(struct plt_pci_device *pci_dev);
813 : : int __roc_api roc_npa_lf_init_cb_register(roc_npa_lf_init_cb_t cb);
814 : :
815 : : /* Debug */
816 : : int __roc_api roc_npa_ctx_dump(void);
817 : : int __roc_api roc_npa_dump(void);
818 : :
819 : : /* Reset operation performance counter. */
820 : : int __roc_api roc_npa_pool_op_pc_reset(uint64_t aura_handle);
821 : :
822 : : int __roc_api roc_npa_aura_drop_set(uint64_t aura_handle, uint64_t limit,
823 : : bool ena);
824 : :
825 : : void __roc_api roc_npa_dev_lock(void);
826 : : void __roc_api roc_npa_dev_unlock(void);
827 : :
828 : : #endif /* _ROC_NPA_H_ */
|