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#include <asm/octeon/octeon.h>
34
35#include <asm/octeon/cvmx-config.h>
36
37#include <asm/octeon/cvmx-fpa.h>
38#include <asm/octeon/cvmx-pip.h>
39#include <asm/octeon/cvmx-pko.h>
40#include <asm/octeon/cvmx-ipd.h>
41#include <asm/octeon/cvmx-spi.h>
42#include <asm/octeon/cvmx-helper.h>
43#include <asm/octeon/cvmx-helper-board.h>
44
45#include <asm/octeon/cvmx-pip-defs.h>
46#include <asm/octeon/cvmx-smix-defs.h>
47#include <asm/octeon/cvmx-asxx-defs.h>
48
49
50
51
52
53
54
55
56void (*cvmx_override_pko_queue_priority) (int pko_port,
57 uint64_t priorities[16]);
58
59
60
61
62
63
64
65
66
67void (*cvmx_override_ipd_port_setup) (int ipd_port);
68
69
70static int interface_port_count[5];
71
72
73
74
75
76
77
78
79
80int cvmx_helper_get_number_of_interfaces(void)
81{
82 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
83 return 9;
84 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
85 return 4;
86 if (OCTEON_IS_MODEL(OCTEON_CN7XXX))
87 return 5;
88 else
89 return 3;
90}
91EXPORT_SYMBOL_GPL(cvmx_helper_get_number_of_interfaces);
92
93
94
95
96
97
98
99
100
101
102int cvmx_helper_ports_on_interface(int interface)
103{
104 return interface_port_count[interface];
105}
106EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface);
107
108
109
110
111
112static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface)
113{
114 union cvmx_mio_qlmx_cfg qlm_cfg;
115 switch (interface) {
116 case 0:
117 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
118
119 if (qlm_cfg.s.qlm_spd == 15)
120 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
121
122 if (qlm_cfg.s.qlm_cfg == 2)
123 return CVMX_HELPER_INTERFACE_MODE_SGMII;
124 else if (qlm_cfg.s.qlm_cfg == 3)
125 return CVMX_HELPER_INTERFACE_MODE_XAUI;
126 else
127 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
128 case 2:
129 case 3:
130 case 4:
131 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(interface));
132
133 if (qlm_cfg.s.qlm_spd == 15)
134 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
135
136 if (qlm_cfg.s.qlm_cfg == 2)
137 return CVMX_HELPER_INTERFACE_MODE_SGMII;
138 else if (qlm_cfg.s.qlm_cfg == 3)
139 return CVMX_HELPER_INTERFACE_MODE_XAUI;
140 else
141 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
142 case 7:
143 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(3));
144
145 if (qlm_cfg.s.qlm_spd == 15) {
146 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
147 } else if (qlm_cfg.s.qlm_cfg != 0) {
148 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
149 if (qlm_cfg.s.qlm_cfg != 0)
150 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
151 }
152 return CVMX_HELPER_INTERFACE_MODE_NPI;
153 case 8:
154 return CVMX_HELPER_INTERFACE_MODE_LOOP;
155 default:
156 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
157 }
158}
159
160
161
162
163
164static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)
165{
166 union cvmx_gmxx_inf_mode mode;
167
168 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
169 return __cvmx_get_mode_cn68xx(interface);
170
171 if (interface == 2)
172 return CVMX_HELPER_INTERFACE_MODE_NPI;
173
174 if (interface == 3)
175 return CVMX_HELPER_INTERFACE_MODE_LOOP;
176
177
178 if ((OCTEON_IS_MODEL(OCTEON_CN63XX) &&
179 (interface == 4 || interface == 5)) ||
180 (OCTEON_IS_MODEL(OCTEON_CN66XX) &&
181 interface >= 4 && interface <= 7)) {
182 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
183 }
184
185 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
186 union cvmx_mio_qlmx_cfg mio_qlm_cfg;
187
188
189 if (interface == 0)
190 mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
191 else if (interface == 1)
192 mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
193 else
194 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
195
196 if (mio_qlm_cfg.s.qlm_spd == 15)
197 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
198
199 if (mio_qlm_cfg.s.qlm_cfg == 9)
200 return CVMX_HELPER_INTERFACE_MODE_SGMII;
201 else if (mio_qlm_cfg.s.qlm_cfg == 11)
202 return CVMX_HELPER_INTERFACE_MODE_XAUI;
203 else
204 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
205 } else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) {
206 union cvmx_mio_qlmx_cfg qlm_cfg;
207
208 if (interface == 0) {
209 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
210 if (qlm_cfg.s.qlm_cfg == 2)
211 return CVMX_HELPER_INTERFACE_MODE_SGMII;
212 else if (qlm_cfg.s.qlm_cfg == 3)
213 return CVMX_HELPER_INTERFACE_MODE_XAUI;
214 else
215 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
216 } else if (interface == 1) {
217 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
218 if (qlm_cfg.s.qlm_cfg == 2)
219 return CVMX_HELPER_INTERFACE_MODE_SGMII;
220 else if (qlm_cfg.s.qlm_cfg == 3)
221 return CVMX_HELPER_INTERFACE_MODE_XAUI;
222 else
223 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
224 }
225 } else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) {
226 if (interface == 0) {
227 union cvmx_mio_qlmx_cfg qlm_cfg;
228 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
229 if (qlm_cfg.s.qlm_cfg == 2)
230 return CVMX_HELPER_INTERFACE_MODE_SGMII;
231 }
232 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
233 }
234
235 if (interface == 1 && OCTEON_IS_MODEL(OCTEON_CN63XX))
236 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
237
238 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
239
240 if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
241 switch (mode.cn63xx.mode) {
242 case 0:
243 return CVMX_HELPER_INTERFACE_MODE_SGMII;
244 case 1:
245 return CVMX_HELPER_INTERFACE_MODE_XAUI;
246 default:
247 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
248 }
249 } else {
250 if (!mode.s.en)
251 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
252
253 if (mode.s.type)
254 return CVMX_HELPER_INTERFACE_MODE_GMII;
255 else
256 return CVMX_HELPER_INTERFACE_MODE_RGMII;
257 }
258}
259
260
261
262
263
264static cvmx_helper_interface_mode_t __cvmx_get_mode_cn7xxx(int interface)
265{
266 union cvmx_gmxx_inf_mode mode;
267
268 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
269
270 switch (interface) {
271 case 0:
272 case 1:
273 switch (mode.cn68xx.mode) {
274 case 0:
275 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
276 case 1:
277 case 2:
278 return CVMX_HELPER_INTERFACE_MODE_SGMII;
279 case 3:
280 return CVMX_HELPER_INTERFACE_MODE_XAUI;
281 default:
282 return CVMX_HELPER_INTERFACE_MODE_SGMII;
283 }
284 case 2:
285 return CVMX_HELPER_INTERFACE_MODE_NPI;
286 case 3:
287 return CVMX_HELPER_INTERFACE_MODE_LOOP;
288 case 4:
289 return CVMX_HELPER_INTERFACE_MODE_RGMII;
290 default:
291 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
292 }
293}
294
295
296
297
298
299
300
301
302
303
304
305cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
306{
307 union cvmx_gmxx_inf_mode mode;
308
309 if (interface < 0 ||
310 interface >= cvmx_helper_get_number_of_interfaces())
311 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
312
313
314
315
316 if (OCTEON_IS_MODEL(OCTEON_CN7XXX))
317 return __cvmx_get_mode_cn7xxx(interface);
318
319
320
321
322 if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
323 return __cvmx_get_mode_octeon2(interface);
324
325
326
327
328 if (interface == 2)
329 return CVMX_HELPER_INTERFACE_MODE_NPI;
330
331 if (interface == 3) {
332 if (OCTEON_IS_MODEL(OCTEON_CN56XX)
333 || OCTEON_IS_MODEL(OCTEON_CN52XX))
334 return CVMX_HELPER_INTERFACE_MODE_LOOP;
335 else
336 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
337 }
338
339 if (interface == 0
340 && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5
341 && cvmx_sysinfo_get()->board_rev_major == 1) {
342
343
344
345
346
347
348
349
350
351
352 return CVMX_HELPER_INTERFACE_MODE_GMII;
353 }
354
355
356 if ((interface == 1)
357 && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX)
358 || OCTEON_IS_MODEL(OCTEON_CN50XX)
359 || OCTEON_IS_MODEL(OCTEON_CN52XX)))
360 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
361
362 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
363
364 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
365 switch (mode.cn56xx.mode) {
366 case 0:
367 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
368 case 1:
369 return CVMX_HELPER_INTERFACE_MODE_XAUI;
370 case 2:
371 return CVMX_HELPER_INTERFACE_MODE_SGMII;
372 case 3:
373 return CVMX_HELPER_INTERFACE_MODE_PICMG;
374 default:
375 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
376 }
377 } else {
378 if (!mode.s.en)
379 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
380
381 if (mode.s.type) {
382 if (OCTEON_IS_MODEL(OCTEON_CN38XX)
383 || OCTEON_IS_MODEL(OCTEON_CN58XX))
384 return CVMX_HELPER_INTERFACE_MODE_SPI;
385 else
386 return CVMX_HELPER_INTERFACE_MODE_GMII;
387 } else
388 return CVMX_HELPER_INTERFACE_MODE_RGMII;
389 }
390}
391EXPORT_SYMBOL_GPL(cvmx_helper_interface_get_mode);
392
393
394
395
396
397
398
399
400
401
402
403
404static int __cvmx_helper_port_setup_ipd(int ipd_port)
405{
406 union cvmx_pip_prt_cfgx port_config;
407 union cvmx_pip_prt_tagx tag_config;
408
409 port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
410 tag_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port));
411
412
413 port_config.s.qos = ipd_port & 0x7;
414
415
416 port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE;
417
418 tag_config.s.ip6_src_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP;
419 tag_config.s.ip6_dst_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_IP;
420 tag_config.s.ip6_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT;
421 tag_config.s.ip6_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT;
422 tag_config.s.ip6_nxth_flag = CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER;
423 tag_config.s.ip4_src_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP;
424 tag_config.s.ip4_dst_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_IP;
425 tag_config.s.ip4_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT;
426 tag_config.s.ip4_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT;
427 tag_config.s.ip4_pctl_flag = CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL;
428 tag_config.s.inc_prt_flag = CVMX_HELPER_INPUT_TAG_INPUT_PORT;
429 tag_config.s.tcp6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
430 tag_config.s.tcp4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
431 tag_config.s.ip6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
432 tag_config.s.ip4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
433 tag_config.s.non_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
434
435 tag_config.s.grp = 0;
436
437 cvmx_pip_config_port(ipd_port, port_config, tag_config);
438
439
440 if (cvmx_override_ipd_port_setup)
441 cvmx_override_ipd_port_setup(ipd_port);
442
443 return 0;
444}
445
446
447
448
449
450
451
452
453
454
455int cvmx_helper_interface_enumerate(int interface)
456{
457 switch (cvmx_helper_interface_get_mode(interface)) {
458
459 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
460 case CVMX_HELPER_INTERFACE_MODE_PCIE:
461 interface_port_count[interface] = 0;
462 break;
463
464 case CVMX_HELPER_INTERFACE_MODE_XAUI:
465 interface_port_count[interface] =
466 __cvmx_helper_xaui_enumerate(interface);
467 break;
468
469
470
471
472 case CVMX_HELPER_INTERFACE_MODE_RGMII:
473 case CVMX_HELPER_INTERFACE_MODE_GMII:
474 interface_port_count[interface] =
475 __cvmx_helper_rgmii_enumerate(interface);
476 break;
477
478
479
480
481 case CVMX_HELPER_INTERFACE_MODE_SPI:
482 interface_port_count[interface] =
483 __cvmx_helper_spi_enumerate(interface);
484 break;
485
486
487
488
489 case CVMX_HELPER_INTERFACE_MODE_SGMII:
490 case CVMX_HELPER_INTERFACE_MODE_PICMG:
491 interface_port_count[interface] =
492 __cvmx_helper_sgmii_enumerate(interface);
493 break;
494
495 case CVMX_HELPER_INTERFACE_MODE_NPI:
496 interface_port_count[interface] =
497 __cvmx_helper_npi_enumerate(interface);
498 break;
499
500
501
502
503 case CVMX_HELPER_INTERFACE_MODE_LOOP:
504 interface_port_count[interface] =
505 __cvmx_helper_loop_enumerate(interface);
506 break;
507 }
508
509 interface_port_count[interface] =
510 __cvmx_helper_board_interface_probe(interface,
511 interface_port_count
512 [interface]);
513
514
515 CVMX_SYNCWS;
516
517 return 0;
518}
519
520
521
522
523
524
525
526
527
528
529
530
531int cvmx_helper_interface_probe(int interface)
532{
533 cvmx_helper_interface_enumerate(interface);
534
535
536
537 switch (cvmx_helper_interface_get_mode(interface)) {
538
539 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
540 case CVMX_HELPER_INTERFACE_MODE_PCIE:
541 break;
542
543 case CVMX_HELPER_INTERFACE_MODE_XAUI:
544 __cvmx_helper_xaui_probe(interface);
545 break;
546
547
548
549
550 case CVMX_HELPER_INTERFACE_MODE_RGMII:
551 case CVMX_HELPER_INTERFACE_MODE_GMII:
552 __cvmx_helper_rgmii_probe(interface);
553 break;
554
555
556
557
558 case CVMX_HELPER_INTERFACE_MODE_SPI:
559 __cvmx_helper_spi_probe(interface);
560 break;
561
562
563
564
565 case CVMX_HELPER_INTERFACE_MODE_SGMII:
566 case CVMX_HELPER_INTERFACE_MODE_PICMG:
567 __cvmx_helper_sgmii_probe(interface);
568 break;
569
570 case CVMX_HELPER_INTERFACE_MODE_NPI:
571 __cvmx_helper_npi_probe(interface);
572 break;
573
574
575
576
577 case CVMX_HELPER_INTERFACE_MODE_LOOP:
578 __cvmx_helper_loop_probe(interface);
579 break;
580 }
581
582
583 CVMX_SYNCWS;
584
585 return 0;
586}
587
588
589
590
591
592
593
594
595
596
597
598static int __cvmx_helper_interface_setup_ipd(int interface)
599{
600 int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
601 int num_ports = interface_port_count[interface];
602
603 while (num_ports--) {
604 __cvmx_helper_port_setup_ipd(ipd_port);
605 ipd_port++;
606 }
607 return 0;
608}
609
610
611
612
613
614
615
616static int __cvmx_helper_global_setup_ipd(void)
617{
618
619 cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE / 8,
620 CVMX_HELPER_FIRST_MBUFF_SKIP / 8,
621 CVMX_HELPER_NOT_FIRST_MBUFF_SKIP / 8,
622
623 (CVMX_HELPER_FIRST_MBUFF_SKIP + 8) / 128,
624
625 (CVMX_HELPER_NOT_FIRST_MBUFF_SKIP + 8) / 128,
626 CVMX_FPA_WQE_POOL,
627 CVMX_IPD_OPC_MODE_STT,
628 CVMX_HELPER_ENABLE_BACK_PRESSURE);
629 return 0;
630}
631
632
633
634
635
636
637
638
639
640
641static int __cvmx_helper_interface_setup_pko(int interface)
642{
643
644
645
646
647
648
649
650
651
652
653
654
655 uint64_t priorities[16] =
656 { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 };
657
658
659
660
661
662
663 int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
664 int num_ports = interface_port_count[interface];
665 while (num_ports--) {
666
667
668
669
670 if (cvmx_override_pko_queue_priority)
671 cvmx_override_pko_queue_priority(ipd_port, priorities);
672
673 cvmx_pko_config_port(ipd_port,
674 cvmx_pko_get_base_queue_per_core(ipd_port,
675 0),
676 cvmx_pko_get_num_queues(ipd_port),
677 priorities);
678 ipd_port++;
679 }
680 return 0;
681}
682
683
684
685
686
687
688
689static int __cvmx_helper_global_setup_pko(void)
690{
691
692
693
694
695 union cvmx_iob_fau_timeout fau_to;
696 fau_to.u64 = 0;
697 fau_to.s.tout_val = 0xfff;
698 fau_to.s.tout_enb = 0;
699 cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64);
700
701 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
702 union cvmx_pko_reg_min_pkt min_pkt;
703
704 min_pkt.u64 = 0;
705 min_pkt.s.size1 = 59;
706 min_pkt.s.size2 = 59;
707 min_pkt.s.size3 = 59;
708 min_pkt.s.size4 = 59;
709 min_pkt.s.size5 = 59;
710 min_pkt.s.size6 = 59;
711 min_pkt.s.size7 = 59;
712 cvmx_write_csr(CVMX_PKO_REG_MIN_PKT, min_pkt.u64);
713 }
714
715 return 0;
716}
717
718
719
720
721
722
723static int __cvmx_helper_global_setup_backpressure(void)
724{
725#if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE
726
727
728 int num_interfaces = cvmx_helper_get_number_of_interfaces();
729 int interface;
730 for (interface = 0; interface < num_interfaces; interface++) {
731 switch (cvmx_helper_interface_get_mode(interface)) {
732 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
733 case CVMX_HELPER_INTERFACE_MODE_PCIE:
734 case CVMX_HELPER_INTERFACE_MODE_NPI:
735 case CVMX_HELPER_INTERFACE_MODE_LOOP:
736 case CVMX_HELPER_INTERFACE_MODE_XAUI:
737 break;
738 case CVMX_HELPER_INTERFACE_MODE_RGMII:
739 case CVMX_HELPER_INTERFACE_MODE_GMII:
740 case CVMX_HELPER_INTERFACE_MODE_SPI:
741 case CVMX_HELPER_INTERFACE_MODE_SGMII:
742 case CVMX_HELPER_INTERFACE_MODE_PICMG:
743 cvmx_gmx_set_backpressure_override(interface, 0xf);
744 break;
745 }
746 }
747#endif
748
749 return 0;
750}
751
752
753
754
755
756
757
758
759
760
761
762
763static int __cvmx_helper_packet_hardware_enable(int interface)
764{
765 int result = 0;
766 switch (cvmx_helper_interface_get_mode(interface)) {
767
768 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
769 case CVMX_HELPER_INTERFACE_MODE_PCIE:
770
771 break;
772
773 case CVMX_HELPER_INTERFACE_MODE_XAUI:
774 result = __cvmx_helper_xaui_enable(interface);
775 break;
776
777
778
779
780 case CVMX_HELPER_INTERFACE_MODE_RGMII:
781 case CVMX_HELPER_INTERFACE_MODE_GMII:
782 result = __cvmx_helper_rgmii_enable(interface);
783 break;
784
785
786
787
788 case CVMX_HELPER_INTERFACE_MODE_SPI:
789 result = __cvmx_helper_spi_enable(interface);
790 break;
791
792
793
794
795 case CVMX_HELPER_INTERFACE_MODE_SGMII:
796 case CVMX_HELPER_INTERFACE_MODE_PICMG:
797 result = __cvmx_helper_sgmii_enable(interface);
798 break;
799
800 case CVMX_HELPER_INTERFACE_MODE_NPI:
801 result = __cvmx_helper_npi_enable(interface);
802 break;
803
804
805
806
807 case CVMX_HELPER_INTERFACE_MODE_LOOP:
808 result = __cvmx_helper_loop_enable(interface);
809 break;
810 }
811 result |= __cvmx_helper_board_hardware_enable(interface);
812 return result;
813}
814
815
816
817
818
819
820
821int __cvmx_helper_errata_fix_ipd_ptr_alignment(void)
822{
823#define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \
824 (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_FIRST_MBUFF_SKIP)
825#define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \
826 (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_NOT_FIRST_MBUFF_SKIP)
827#define FIX_IPD_OUTPORT 0
828
829#define INTERFACE(port) (port >> 4)
830#define INDEX(port) (port & 0xf)
831 uint64_t *p64;
832 cvmx_pko_command_word0_t pko_command;
833 union cvmx_buf_ptr g_buffer, pkt_buffer;
834 cvmx_wqe_t *work;
835 int size, num_segs = 0, wqe_pcnt, pkt_pcnt;
836 union cvmx_gmxx_prtx_cfg gmx_cfg;
837 int retry_cnt;
838 int retry_loop_cnt;
839 int i;
840
841
842 uint64_t prtx_cfg =
843 cvmx_read_csr(CVMX_GMXX_PRTX_CFG
844 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
845 uint64_t tx_ptr_en =
846 cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
847 uint64_t rx_ptr_en =
848 cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
849 uint64_t rxx_jabber =
850 cvmx_read_csr(CVMX_GMXX_RXX_JABBER
851 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
852 uint64_t frame_max =
853 cvmx_read_csr(CVMX_GMXX_RXX_FRM_MAX
854 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
855
856
857 cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT);
858
859
860
861
862
863 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 0);
864
865 __delay(100000000ull);
866
867 for (retry_loop_cnt = 0; retry_loop_cnt < 10; retry_loop_cnt++) {
868 retry_cnt = 100000;
869 wqe_pcnt = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
870 pkt_pcnt = (wqe_pcnt >> 7) & 0x7f;
871 wqe_pcnt &= 0x7f;
872
873 num_segs = (2 + pkt_pcnt - wqe_pcnt) & 3;
874
875 if (num_segs == 0)
876 goto fix_ipd_exit;
877
878 num_segs += 1;
879
880 size =
881 FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES +
882 ((num_segs - 1) * FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES) -
883 (FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES / 2);
884
885 cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)),
886 1 << INDEX(FIX_IPD_OUTPORT));
887 CVMX_SYNC;
888
889 g_buffer.u64 = 0;
890 g_buffer.s.addr =
891 cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_WQE_POOL));
892 if (g_buffer.s.addr == 0) {
893 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
894 "buffer allocation failure.\n");
895 goto fix_ipd_exit;
896 }
897
898 g_buffer.s.pool = CVMX_FPA_WQE_POOL;
899 g_buffer.s.size = num_segs;
900
901 pkt_buffer.u64 = 0;
902 pkt_buffer.s.addr =
903 cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL));
904 if (pkt_buffer.s.addr == 0) {
905 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
906 "buffer allocation failure.\n");
907 goto fix_ipd_exit;
908 }
909 pkt_buffer.s.i = 1;
910 pkt_buffer.s.pool = CVMX_FPA_PACKET_POOL;
911 pkt_buffer.s.size = FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES;
912
913 p64 = (uint64_t *) cvmx_phys_to_ptr(pkt_buffer.s.addr);
914 p64[0] = 0xffffffffffff0000ull;
915 p64[1] = 0x08004510ull;
916 p64[2] = ((uint64_t) (size - 14) << 48) | 0x5ae740004000ull;
917 p64[3] = 0x3a5fc0a81073c0a8ull;
918
919 for (i = 0; i < num_segs; i++) {
920 if (i > 0)
921 pkt_buffer.s.size =
922 FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES;
923
924 if (i == (num_segs - 1))
925 pkt_buffer.s.i = 0;
926
927 *(uint64_t *) cvmx_phys_to_ptr(g_buffer.s.addr +
928 8 * i) = pkt_buffer.u64;
929 }
930
931
932 pko_command.u64 = 0;
933 pko_command.s.segs = num_segs;
934 pko_command.s.total_bytes = size;
935 pko_command.s.dontfree = 0;
936 pko_command.s.gather = 1;
937
938 gmx_cfg.u64 =
939 cvmx_read_csr(CVMX_GMXX_PRTX_CFG
940 (INDEX(FIX_IPD_OUTPORT),
941 INTERFACE(FIX_IPD_OUTPORT)));
942 gmx_cfg.s.en = 1;
943 cvmx_write_csr(CVMX_GMXX_PRTX_CFG
944 (INDEX(FIX_IPD_OUTPORT),
945 INTERFACE(FIX_IPD_OUTPORT)), gmx_cfg.u64);
946 cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
947 1 << INDEX(FIX_IPD_OUTPORT));
948 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
949 1 << INDEX(FIX_IPD_OUTPORT));
950
951 cvmx_write_csr(CVMX_GMXX_RXX_JABBER
952 (INDEX(FIX_IPD_OUTPORT),
953 INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
954 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
955 (INDEX(FIX_IPD_OUTPORT),
956 INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
957
958 cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT,
959 cvmx_pko_get_base_queue
960 (FIX_IPD_OUTPORT),
961 CVMX_PKO_LOCK_CMD_QUEUE);
962 cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT,
963 cvmx_pko_get_base_queue
964 (FIX_IPD_OUTPORT), pko_command,
965 g_buffer, CVMX_PKO_LOCK_CMD_QUEUE);
966
967 CVMX_SYNC;
968
969 do {
970 work = cvmx_pow_work_request_sync(CVMX_POW_WAIT);
971 retry_cnt--;
972 } while ((work == NULL) && (retry_cnt > 0));
973
974 if (!retry_cnt)
975 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
976 "get_work() timeout occurred.\n");
977
978
979 if (work)
980 cvmx_helper_free_packet_data(work);
981 }
982
983fix_ipd_exit:
984
985
986 cvmx_write_csr(CVMX_GMXX_PRTX_CFG
987 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
988 prtx_cfg);
989 cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
990 tx_ptr_en);
991 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
992 rx_ptr_en);
993 cvmx_write_csr(CVMX_GMXX_RXX_JABBER
994 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
995 rxx_jabber);
996 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
997 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
998 frame_max);
999 cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0);
1000
1001 CVMX_SYNC;
1002 if (num_segs)
1003 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n");
1004
1005 return !!num_segs;
1006
1007}
1008
1009
1010
1011
1012
1013
1014
1015int cvmx_helper_ipd_and_packet_input_enable(void)
1016{
1017 int num_interfaces;
1018 int interface;
1019
1020
1021 cvmx_ipd_enable();
1022
1023
1024
1025
1026
1027
1028 num_interfaces = cvmx_helper_get_number_of_interfaces();
1029 for (interface = 0; interface < num_interfaces; interface++) {
1030 if (cvmx_helper_ports_on_interface(interface) > 0)
1031 __cvmx_helper_packet_hardware_enable(interface);
1032 }
1033
1034
1035 cvmx_pko_enable();
1036
1037 if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1)
1038 || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1))
1039 && (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM))
1040 __cvmx_helper_errata_fix_ipd_ptr_alignment();
1041 return 0;
1042}
1043EXPORT_SYMBOL_GPL(cvmx_helper_ipd_and_packet_input_enable);
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054int cvmx_helper_initialize_packet_io_global(void)
1055{
1056 int result = 0;
1057 int interface;
1058 union cvmx_l2c_cfg l2c_cfg;
1059 union cvmx_smix_en smix_en;
1060 const int num_interfaces = cvmx_helper_get_number_of_interfaces();
1061
1062
1063
1064
1065
1066 if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
1067 __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
1068
1069
1070
1071
1072
1073
1074 l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
1075 l2c_cfg.s.lrf_arb_mode = 0;
1076 l2c_cfg.s.rfb_arb_mode = 0;
1077 cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
1078
1079
1080 smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0));
1081 if (!smix_en.s.en) {
1082 smix_en.s.en = 1;
1083 cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64);
1084 }
1085
1086
1087 if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
1088 !OCTEON_IS_MODEL(OCTEON_CN58XX) &&
1089 !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
1090 smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1));
1091 if (!smix_en.s.en) {
1092 smix_en.s.en = 1;
1093 cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64);
1094 }
1095 }
1096
1097 cvmx_pko_initialize_global();
1098 for (interface = 0; interface < num_interfaces; interface++) {
1099 result |= cvmx_helper_interface_probe(interface);
1100 if (cvmx_helper_ports_on_interface(interface) > 0)
1101 cvmx_dprintf("Interface %d has %d ports (%s)\n",
1102 interface,
1103 cvmx_helper_ports_on_interface(interface),
1104 cvmx_helper_interface_mode_to_string
1105 (cvmx_helper_interface_get_mode
1106 (interface)));
1107 result |= __cvmx_helper_interface_setup_ipd(interface);
1108 result |= __cvmx_helper_interface_setup_pko(interface);
1109 }
1110
1111 result |= __cvmx_helper_global_setup_ipd();
1112 result |= __cvmx_helper_global_setup_pko();
1113
1114
1115 result |= __cvmx_helper_global_setup_backpressure();
1116
1117#if CVMX_HELPER_ENABLE_IPD
1118 result |= cvmx_helper_ipd_and_packet_input_enable();
1119#endif
1120 return result;
1121}
1122EXPORT_SYMBOL_GPL(cvmx_helper_initialize_packet_io_global);
1123
1124
1125
1126
1127
1128
1129int cvmx_helper_initialize_packet_io_local(void)
1130{
1131 return cvmx_pko_initialize_local();
1132}
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
1145{
1146 cvmx_helper_link_info_t result;
1147 int interface = cvmx_helper_get_interface_num(ipd_port);
1148 int index = cvmx_helper_get_interface_index_num(ipd_port);
1149
1150
1151
1152 result.u64 = 0;
1153
1154 if (index >= cvmx_helper_ports_on_interface(interface))
1155 return result;
1156
1157 switch (cvmx_helper_interface_get_mode(interface)) {
1158 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
1159 case CVMX_HELPER_INTERFACE_MODE_PCIE:
1160
1161 break;
1162 case CVMX_HELPER_INTERFACE_MODE_XAUI:
1163 result = __cvmx_helper_xaui_link_get(ipd_port);
1164 break;
1165 case CVMX_HELPER_INTERFACE_MODE_GMII:
1166 if (index == 0)
1167 result = __cvmx_helper_rgmii_link_get(ipd_port);
1168 else {
1169 result.s.full_duplex = 1;
1170 result.s.link_up = 1;
1171 result.s.speed = 1000;
1172 }
1173 break;
1174 case CVMX_HELPER_INTERFACE_MODE_RGMII:
1175 result = __cvmx_helper_rgmii_link_get(ipd_port);
1176 break;
1177 case CVMX_HELPER_INTERFACE_MODE_SPI:
1178 result = __cvmx_helper_spi_link_get(ipd_port);
1179 break;
1180 case CVMX_HELPER_INTERFACE_MODE_SGMII:
1181 case CVMX_HELPER_INTERFACE_MODE_PICMG:
1182 result = __cvmx_helper_sgmii_link_get(ipd_port);
1183 break;
1184 case CVMX_HELPER_INTERFACE_MODE_NPI:
1185 case CVMX_HELPER_INTERFACE_MODE_LOOP:
1186
1187 break;
1188 }
1189 return result;
1190}
1191EXPORT_SYMBOL_GPL(cvmx_helper_link_get);
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
1205{
1206 int result = -1;
1207 int interface = cvmx_helper_get_interface_num(ipd_port);
1208 int index = cvmx_helper_get_interface_index_num(ipd_port);
1209
1210 if (index >= cvmx_helper_ports_on_interface(interface))
1211 return -1;
1212
1213 switch (cvmx_helper_interface_get_mode(interface)) {
1214 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
1215 case CVMX_HELPER_INTERFACE_MODE_PCIE:
1216 break;
1217 case CVMX_HELPER_INTERFACE_MODE_XAUI:
1218 result = __cvmx_helper_xaui_link_set(ipd_port, link_info);
1219 break;
1220
1221
1222
1223
1224 case CVMX_HELPER_INTERFACE_MODE_RGMII:
1225 case CVMX_HELPER_INTERFACE_MODE_GMII:
1226 result = __cvmx_helper_rgmii_link_set(ipd_port, link_info);
1227 break;
1228 case CVMX_HELPER_INTERFACE_MODE_SPI:
1229 result = __cvmx_helper_spi_link_set(ipd_port, link_info);
1230 break;
1231 case CVMX_HELPER_INTERFACE_MODE_SGMII:
1232 case CVMX_HELPER_INTERFACE_MODE_PICMG:
1233 result = __cvmx_helper_sgmii_link_set(ipd_port, link_info);
1234 break;
1235 case CVMX_HELPER_INTERFACE_MODE_NPI:
1236 case CVMX_HELPER_INTERFACE_MODE_LOOP:
1237 break;
1238 }
1239 return result;
1240}
1241EXPORT_SYMBOL_GPL(cvmx_helper_link_set);
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256int cvmx_helper_configure_loopback(int ipd_port, int enable_internal,
1257 int enable_external)
1258{
1259 int result = -1;
1260 int interface = cvmx_helper_get_interface_num(ipd_port);
1261 int index = cvmx_helper_get_interface_index_num(ipd_port);
1262
1263 if (index >= cvmx_helper_ports_on_interface(interface))
1264 return -1;
1265
1266 switch (cvmx_helper_interface_get_mode(interface)) {
1267 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
1268 case CVMX_HELPER_INTERFACE_MODE_PCIE:
1269 case CVMX_HELPER_INTERFACE_MODE_SPI:
1270 case CVMX_HELPER_INTERFACE_MODE_NPI:
1271 case CVMX_HELPER_INTERFACE_MODE_LOOP:
1272 break;
1273 case CVMX_HELPER_INTERFACE_MODE_XAUI:
1274 result =
1275 __cvmx_helper_xaui_configure_loopback(ipd_port,
1276 enable_internal,
1277 enable_external);
1278 break;
1279 case CVMX_HELPER_INTERFACE_MODE_RGMII:
1280 case CVMX_HELPER_INTERFACE_MODE_GMII:
1281 result =
1282 __cvmx_helper_rgmii_configure_loopback(ipd_port,
1283 enable_internal,
1284 enable_external);
1285 break;
1286 case CVMX_HELPER_INTERFACE_MODE_SGMII:
1287 case CVMX_HELPER_INTERFACE_MODE_PICMG:
1288 result =
1289 __cvmx_helper_sgmii_configure_loopback(ipd_port,
1290 enable_internal,
1291 enable_external);
1292 break;
1293 }
1294 return result;
1295}
1296