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