This source file includes following definitions.
- cvmx_pko_doorbell
- cvmx_pko_send_packet_prepare
- cvmx_pko_send_packet_finish
- cvmx_pko_send_packet_finish3
- cvmx_pko_get_base_queue_per_core
- cvmx_pko_get_base_queue
- cvmx_pko_get_num_queues
- cvmx_pko_get_port_status
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 #ifndef __CVMX_PKO_H__
59 #define __CVMX_PKO_H__
60
61 #include <asm/octeon/cvmx-fpa.h>
62 #include <asm/octeon/cvmx-pow.h>
63 #include <asm/octeon/cvmx-cmd-queue.h>
64 #include <asm/octeon/cvmx-pko-defs.h>
65
66
67
68
69 #define CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST (1)
70
71 #define CVMX_PKO_MAX_OUTPUT_QUEUES_STATIC 256
72 #define CVMX_PKO_MAX_OUTPUT_QUEUES ((OCTEON_IS_MODEL(OCTEON_CN31XX) || \
73 OCTEON_IS_MODEL(OCTEON_CN3010) || OCTEON_IS_MODEL(OCTEON_CN3005) || \
74 OCTEON_IS_MODEL(OCTEON_CN50XX)) ? 32 : \
75 (OCTEON_IS_MODEL(OCTEON_CN58XX) || \
76 OCTEON_IS_MODEL(OCTEON_CN56XX)) ? 256 : 128)
77 #define CVMX_PKO_NUM_OUTPUT_PORTS 40
78
79 #define CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID 63
80 #define CVMX_PKO_QUEUE_STATIC_PRIORITY 9
81 #define CVMX_PKO_ILLEGAL_QUEUE 0xFFFF
82 #define CVMX_PKO_MAX_QUEUE_DEPTH 0
83
84 typedef enum {
85 CVMX_PKO_SUCCESS,
86 CVMX_PKO_INVALID_PORT,
87 CVMX_PKO_INVALID_QUEUE,
88 CVMX_PKO_INVALID_PRIORITY,
89 CVMX_PKO_NO_MEMORY,
90 CVMX_PKO_PORT_ALREADY_SETUP,
91 CVMX_PKO_CMD_QUEUE_INIT_ERROR
92 } cvmx_pko_status_t;
93
94
95
96
97 typedef enum {
98
99
100
101
102
103 CVMX_PKO_LOCK_NONE = 0,
104
105
106
107
108
109 CVMX_PKO_LOCK_ATOMIC_TAG = 1,
110
111
112
113
114
115 CVMX_PKO_LOCK_CMD_QUEUE = 2,
116 } cvmx_pko_lock_t;
117
118 typedef struct {
119 uint32_t packets;
120 uint64_t octets;
121 uint64_t doorbell;
122 } cvmx_pko_port_status_t;
123
124
125
126
127 typedef union {
128 uint64_t u64;
129 struct {
130 #ifdef __BIG_ENDIAN_BITFIELD
131
132 uint64_t mem_space:2;
133
134 uint64_t reserved:13;
135
136 uint64_t is_io:1;
137
138 uint64_t did:8;
139
140 uint64_t reserved2:4;
141
142 uint64_t reserved3:18;
143
144
145
146
147 uint64_t port:6;
148
149
150
151
152 uint64_t queue:9;
153
154 uint64_t reserved4:3;
155 #else
156 uint64_t reserved4:3;
157 uint64_t queue:9;
158 uint64_t port:9;
159 uint64_t reserved3:15;
160 uint64_t reserved2:4;
161 uint64_t did:8;
162 uint64_t is_io:1;
163 uint64_t reserved:13;
164 uint64_t mem_space:2;
165 #endif
166 } s;
167 } cvmx_pko_doorbell_address_t;
168
169
170
171
172 typedef union {
173 uint64_t u64;
174 struct {
175 #ifdef __BIG_ENDIAN_BITFIELD
176
177
178
179
180 uint64_t size1:2;
181
182
183
184
185 uint64_t size0:2;
186
187
188
189
190 uint64_t subone1:1;
191
192
193
194
195 uint64_t reg1:11;
196
197 uint64_t subone0:1;
198
199 uint64_t reg0:11;
200
201
202
203
204 uint64_t le:1;
205
206
207
208
209 uint64_t n2:1;
210
211
212
213
214 uint64_t wqp:1;
215
216 uint64_t rsp:1;
217
218
219
220
221 uint64_t gather:1;
222
223
224
225
226
227 uint64_t ipoffp1:7;
228
229
230
231
232 uint64_t ignore_i:1;
233
234
235
236
237 uint64_t dontfree:1;
238
239
240
241
242 uint64_t segs:6;
243
244 uint64_t total_bytes:16;
245 #else
246 uint64_t total_bytes:16;
247 uint64_t segs:6;
248 uint64_t dontfree:1;
249 uint64_t ignore_i:1;
250 uint64_t ipoffp1:7;
251 uint64_t gather:1;
252 uint64_t rsp:1;
253 uint64_t wqp:1;
254 uint64_t n2:1;
255 uint64_t le:1;
256 uint64_t reg0:11;
257 uint64_t subone0:1;
258 uint64_t reg1:11;
259 uint64_t subone1:1;
260 uint64_t size0:2;
261 uint64_t size1:2;
262 #endif
263 } s;
264 } cvmx_pko_command_word0_t;
265
266
267
268
269
270
271 typedef struct {
272
273 uint64_t *start_ptr;
274 } cvmx_pko_state_elem_t;
275
276
277
278
279
280 extern void cvmx_pko_initialize_global(void);
281 extern int cvmx_pko_initialize_local(void);
282
283
284
285
286
287 extern void cvmx_pko_enable(void);
288
289
290
291
292 extern void cvmx_pko_disable(void);
293
294
295
296
297
298 extern void cvmx_pko_shutdown(void);
299
300
301
302
303
304
305
306
307
308
309
310
311 extern cvmx_pko_status_t cvmx_pko_config_port(uint64_t port,
312 uint64_t base_queue,
313 uint64_t num_queues,
314 const uint64_t priority[]);
315
316
317
318
319
320
321
322
323
324
325
326 static inline void cvmx_pko_doorbell(uint64_t port, uint64_t queue,
327 uint64_t len)
328 {
329 cvmx_pko_doorbell_address_t ptr;
330
331 ptr.u64 = 0;
332 ptr.s.mem_space = CVMX_IO_SEG;
333 ptr.s.did = CVMX_OCT_DID_PKT_SEND;
334 ptr.s.is_io = 1;
335 ptr.s.port = port;
336 ptr.s.queue = queue;
337
338
339
340
341 CVMX_SYNCWS;
342 cvmx_write_io(ptr.u64, len);
343 }
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378 static inline void cvmx_pko_send_packet_prepare(uint64_t port, uint64_t queue,
379 cvmx_pko_lock_t use_locking)
380 {
381 if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG) {
382
383
384
385
386
387
388
389
390
391
392
393 uint32_t tag =
394 CVMX_TAG_SW_BITS_INTERNAL << CVMX_TAG_SW_SHIFT |
395 CVMX_TAG_SUBGROUP_PKO << CVMX_TAG_SUBGROUP_SHIFT |
396 (CVMX_TAG_SUBGROUP_MASK & queue);
397 cvmx_pow_tag_sw_full((cvmx_wqe_t *) cvmx_phys_to_ptr(0x80), tag,
398 CVMX_POW_TAG_TYPE_ATOMIC, 0);
399 }
400 }
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419 static inline cvmx_pko_status_t cvmx_pko_send_packet_finish(
420 uint64_t port,
421 uint64_t queue,
422 cvmx_pko_command_word0_t pko_command,
423 union cvmx_buf_ptr packet,
424 cvmx_pko_lock_t use_locking)
425 {
426 cvmx_cmd_queue_result_t result;
427 if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
428 cvmx_pow_tag_sw_wait();
429 result = cvmx_cmd_queue_write2(CVMX_CMD_QUEUE_PKO(queue),
430 (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
431 pko_command.u64, packet.u64);
432 if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
433 cvmx_pko_doorbell(port, queue, 2);
434 return CVMX_PKO_SUCCESS;
435 } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
436 || (result == CVMX_CMD_QUEUE_FULL)) {
437 return CVMX_PKO_NO_MEMORY;
438 } else {
439 return CVMX_PKO_INVALID_QUEUE;
440 }
441 }
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462 static inline cvmx_pko_status_t cvmx_pko_send_packet_finish3(
463 uint64_t port,
464 uint64_t queue,
465 cvmx_pko_command_word0_t pko_command,
466 union cvmx_buf_ptr packet,
467 uint64_t addr,
468 cvmx_pko_lock_t use_locking)
469 {
470 cvmx_cmd_queue_result_t result;
471 if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
472 cvmx_pow_tag_sw_wait();
473 result = cvmx_cmd_queue_write3(CVMX_CMD_QUEUE_PKO(queue),
474 (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
475 pko_command.u64, packet.u64, addr);
476 if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
477 cvmx_pko_doorbell(port, queue, 3);
478 return CVMX_PKO_SUCCESS;
479 } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
480 || (result == CVMX_CMD_QUEUE_FULL)) {
481 return CVMX_PKO_NO_MEMORY;
482 } else {
483 return CVMX_PKO_INVALID_QUEUE;
484 }
485 }
486
487
488
489
490
491
492
493
494
495
496
497 static inline int cvmx_pko_get_base_queue_per_core(int port, int core)
498 {
499 #ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
500 #define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0 16
501 #endif
502 #ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
503 #define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1 16
504 #endif
505
506 if (port < CVMX_PKO_MAX_PORTS_INTERFACE0)
507 return port * CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + core;
508 else if (port >= 16 && port < 16 + CVMX_PKO_MAX_PORTS_INTERFACE1)
509 return CVMX_PKO_MAX_PORTS_INTERFACE0 *
510 CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + (port -
511 16) *
512 CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + core;
513 else if ((port >= 32) && (port < 36))
514 return CVMX_PKO_MAX_PORTS_INTERFACE0 *
515 CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
516 CVMX_PKO_MAX_PORTS_INTERFACE1 *
517 CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + (port -
518 32) *
519 CVMX_PKO_QUEUES_PER_PORT_PCI;
520 else if ((port >= 36) && (port < 40))
521 return CVMX_PKO_MAX_PORTS_INTERFACE0 *
522 CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
523 CVMX_PKO_MAX_PORTS_INTERFACE1 *
524 CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 +
525 4 * CVMX_PKO_QUEUES_PER_PORT_PCI + (port -
526 36) *
527 CVMX_PKO_QUEUES_PER_PORT_LOOP;
528 else
529
530
531
532
533 return CVMX_PKO_ILLEGAL_QUEUE;
534 }
535
536
537
538
539
540
541
542
543 static inline int cvmx_pko_get_base_queue(int port)
544 {
545 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
546 return port;
547
548 return cvmx_pko_get_base_queue_per_core(port, 0);
549 }
550
551
552
553
554
555
556
557 static inline int cvmx_pko_get_num_queues(int port)
558 {
559 if (port < 16)
560 return CVMX_PKO_QUEUES_PER_PORT_INTERFACE0;
561 else if (port < 32)
562 return CVMX_PKO_QUEUES_PER_PORT_INTERFACE1;
563 else if (port < 36)
564 return CVMX_PKO_QUEUES_PER_PORT_PCI;
565 else if (port < 40)
566 return CVMX_PKO_QUEUES_PER_PORT_LOOP;
567 else
568 return 0;
569 }
570
571
572
573
574
575
576
577
578 static inline void cvmx_pko_get_port_status(uint64_t port_num, uint64_t clear,
579 cvmx_pko_port_status_t *status)
580 {
581 union cvmx_pko_reg_read_idx pko_reg_read_idx;
582 union cvmx_pko_mem_count0 pko_mem_count0;
583 union cvmx_pko_mem_count1 pko_mem_count1;
584
585 pko_reg_read_idx.u64 = 0;
586 pko_reg_read_idx.s.index = port_num;
587 cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
588
589 pko_mem_count0.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT0);
590 status->packets = pko_mem_count0.s.count;
591 if (clear) {
592 pko_mem_count0.s.count = port_num;
593 cvmx_write_csr(CVMX_PKO_MEM_COUNT0, pko_mem_count0.u64);
594 }
595
596 pko_mem_count1.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT1);
597 status->octets = pko_mem_count1.s.count;
598 if (clear) {
599 pko_mem_count1.s.count = port_num;
600 cvmx_write_csr(CVMX_PKO_MEM_COUNT1, pko_mem_count1.u64);
601 }
602
603 if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
604 union cvmx_pko_mem_debug9 debug9;
605 pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
606 cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
607 debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9);
608 status->doorbell = debug9.cn38xx.doorbell;
609 } else {
610 union cvmx_pko_mem_debug8 debug8;
611 pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
612 cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
613 debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
614 status->doorbell = debug8.cn50xx.doorbell;
615 }
616 }
617
618
619
620
621
622
623
624
625
626
627
628
629 extern int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst);
630
631
632
633
634
635
636
637
638
639
640
641
642 extern int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst);
643
644 #endif