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