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