0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include <linux/bug.h>
0034 #include <asm/octeon/octeon.h>
0035
0036 #include <asm/octeon/cvmx-config.h>
0037
0038 #include <asm/octeon/cvmx-fpa.h>
0039 #include <asm/octeon/cvmx-pip.h>
0040 #include <asm/octeon/cvmx-pko.h>
0041 #include <asm/octeon/cvmx-ipd.h>
0042 #include <asm/octeon/cvmx-spi.h>
0043 #include <asm/octeon/cvmx-helper.h>
0044 #include <asm/octeon/cvmx-helper-board.h>
0045
0046 #include <asm/octeon/cvmx-pip-defs.h>
0047 #include <asm/octeon/cvmx-asxx-defs.h>
0048
0049
0050 static int interface_port_count[9];
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 int cvmx_helper_get_number_of_interfaces(void)
0061 {
0062 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
0063 return 9;
0064 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
0065 if (OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_0))
0066 return 7;
0067 else
0068 return 8;
0069 }
0070 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
0071 return 4;
0072 if (OCTEON_IS_MODEL(OCTEON_CN7XXX))
0073 return 5;
0074 else
0075 return 3;
0076 }
0077 EXPORT_SYMBOL_GPL(cvmx_helper_get_number_of_interfaces);
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 int cvmx_helper_ports_on_interface(int interface)
0089 {
0090 return interface_port_count[interface];
0091 }
0092 EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface);
0093
0094
0095
0096
0097
0098 static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface)
0099 {
0100 union cvmx_mio_qlmx_cfg qlm_cfg;
0101 switch (interface) {
0102 case 0:
0103 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
0104
0105 if (qlm_cfg.s.qlm_spd == 15)
0106 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0107
0108 if (qlm_cfg.s.qlm_cfg == 2)
0109 return CVMX_HELPER_INTERFACE_MODE_SGMII;
0110 else if (qlm_cfg.s.qlm_cfg == 3)
0111 return CVMX_HELPER_INTERFACE_MODE_XAUI;
0112 else
0113 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0114 case 2:
0115 case 3:
0116 case 4:
0117 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(interface));
0118
0119 if (qlm_cfg.s.qlm_spd == 15)
0120 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0121
0122 if (qlm_cfg.s.qlm_cfg == 2)
0123 return CVMX_HELPER_INTERFACE_MODE_SGMII;
0124 else if (qlm_cfg.s.qlm_cfg == 3)
0125 return CVMX_HELPER_INTERFACE_MODE_XAUI;
0126 else
0127 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0128 case 7:
0129 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(3));
0130
0131 if (qlm_cfg.s.qlm_spd == 15) {
0132 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0133 } else if (qlm_cfg.s.qlm_cfg != 0) {
0134 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
0135 if (qlm_cfg.s.qlm_cfg != 0)
0136 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0137 }
0138 return CVMX_HELPER_INTERFACE_MODE_NPI;
0139 case 8:
0140 return CVMX_HELPER_INTERFACE_MODE_LOOP;
0141 default:
0142 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0143 }
0144 }
0145
0146
0147
0148
0149
0150 static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)
0151 {
0152 union cvmx_gmxx_inf_mode mode;
0153
0154 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
0155 return __cvmx_get_mode_cn68xx(interface);
0156
0157 if (interface == 2)
0158 return CVMX_HELPER_INTERFACE_MODE_NPI;
0159
0160 if (interface == 3)
0161 return CVMX_HELPER_INTERFACE_MODE_LOOP;
0162
0163
0164 if ((OCTEON_IS_MODEL(OCTEON_CN63XX) &&
0165 (interface == 4 || interface == 5)) ||
0166 (OCTEON_IS_MODEL(OCTEON_CN66XX) &&
0167 interface >= 4 && interface <= 7)) {
0168 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0169 }
0170
0171 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
0172 union cvmx_mio_qlmx_cfg mio_qlm_cfg;
0173
0174
0175 if (interface == 0)
0176 mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
0177 else if (interface == 1)
0178 mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
0179 else
0180 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0181
0182 if (mio_qlm_cfg.s.qlm_spd == 15)
0183 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0184
0185 if (mio_qlm_cfg.s.qlm_cfg == 9)
0186 return CVMX_HELPER_INTERFACE_MODE_SGMII;
0187 else if (mio_qlm_cfg.s.qlm_cfg == 11)
0188 return CVMX_HELPER_INTERFACE_MODE_XAUI;
0189 else
0190 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0191 } else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) {
0192 union cvmx_mio_qlmx_cfg qlm_cfg;
0193
0194 if (interface == 0) {
0195 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
0196 if (qlm_cfg.s.qlm_cfg == 2)
0197 return CVMX_HELPER_INTERFACE_MODE_SGMII;
0198 else if (qlm_cfg.s.qlm_cfg == 3)
0199 return CVMX_HELPER_INTERFACE_MODE_XAUI;
0200 else
0201 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0202 } else if (interface == 1) {
0203 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
0204 if (qlm_cfg.s.qlm_cfg == 2)
0205 return CVMX_HELPER_INTERFACE_MODE_SGMII;
0206 else if (qlm_cfg.s.qlm_cfg == 3)
0207 return CVMX_HELPER_INTERFACE_MODE_XAUI;
0208 else
0209 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0210 }
0211 } else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) {
0212 if (interface == 0) {
0213 union cvmx_mio_qlmx_cfg qlm_cfg;
0214 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
0215 if (qlm_cfg.s.qlm_cfg == 2)
0216 return CVMX_HELPER_INTERFACE_MODE_SGMII;
0217 }
0218 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0219 }
0220
0221 if (interface == 1 && OCTEON_IS_MODEL(OCTEON_CN63XX))
0222 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0223
0224 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
0225
0226 if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
0227 switch (mode.cn61xx.mode) {
0228 case 0:
0229 return CVMX_HELPER_INTERFACE_MODE_SGMII;
0230 case 1:
0231 return CVMX_HELPER_INTERFACE_MODE_XAUI;
0232 default:
0233 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0234 }
0235 } else {
0236 if (!mode.s.en)
0237 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0238
0239 if (mode.s.type)
0240 return CVMX_HELPER_INTERFACE_MODE_GMII;
0241 else
0242 return CVMX_HELPER_INTERFACE_MODE_RGMII;
0243 }
0244 }
0245
0246
0247
0248
0249
0250 static cvmx_helper_interface_mode_t __cvmx_get_mode_cn7xxx(int interface)
0251 {
0252 union cvmx_gmxx_inf_mode mode;
0253
0254 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
0255
0256 switch (interface) {
0257 case 0:
0258 case 1:
0259 switch (mode.cn68xx.mode) {
0260 case 0:
0261 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0262 case 1:
0263 case 2:
0264 return CVMX_HELPER_INTERFACE_MODE_SGMII;
0265 case 3:
0266 return CVMX_HELPER_INTERFACE_MODE_XAUI;
0267 default:
0268 return CVMX_HELPER_INTERFACE_MODE_SGMII;
0269 }
0270 case 2:
0271 return CVMX_HELPER_INTERFACE_MODE_NPI;
0272 case 3:
0273 return CVMX_HELPER_INTERFACE_MODE_LOOP;
0274 case 4:
0275
0276 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0277 default:
0278 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0279 }
0280 }
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292 cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
0293 {
0294 union cvmx_gmxx_inf_mode mode;
0295
0296 if (interface < 0 ||
0297 interface >= cvmx_helper_get_number_of_interfaces())
0298 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0299
0300
0301
0302
0303 if (OCTEON_IS_MODEL(OCTEON_CN7XXX))
0304 return __cvmx_get_mode_cn7xxx(interface);
0305
0306
0307
0308
0309 if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
0310 return __cvmx_get_mode_octeon2(interface);
0311
0312
0313
0314
0315 if (interface == 2)
0316 return CVMX_HELPER_INTERFACE_MODE_NPI;
0317
0318 if (interface == 3) {
0319 if (OCTEON_IS_MODEL(OCTEON_CN56XX)
0320 || OCTEON_IS_MODEL(OCTEON_CN52XX))
0321 return CVMX_HELPER_INTERFACE_MODE_LOOP;
0322 else
0323 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0324 }
0325
0326
0327 if ((interface == 1)
0328 && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX)
0329 || OCTEON_IS_MODEL(OCTEON_CN50XX)
0330 || OCTEON_IS_MODEL(OCTEON_CN52XX)))
0331 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0332
0333 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
0334
0335 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
0336 switch (mode.cn52xx.mode) {
0337 case 0:
0338 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0339 case 1:
0340 return CVMX_HELPER_INTERFACE_MODE_XAUI;
0341 case 2:
0342 return CVMX_HELPER_INTERFACE_MODE_SGMII;
0343 case 3:
0344 return CVMX_HELPER_INTERFACE_MODE_PICMG;
0345 default:
0346 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0347 }
0348 } else {
0349 if (!mode.s.en)
0350 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
0351
0352 if (mode.s.type) {
0353 if (OCTEON_IS_MODEL(OCTEON_CN38XX)
0354 || OCTEON_IS_MODEL(OCTEON_CN58XX))
0355 return CVMX_HELPER_INTERFACE_MODE_SPI;
0356 else
0357 return CVMX_HELPER_INTERFACE_MODE_GMII;
0358 } else
0359 return CVMX_HELPER_INTERFACE_MODE_RGMII;
0360 }
0361 }
0362 EXPORT_SYMBOL_GPL(cvmx_helper_interface_get_mode);
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375 static int __cvmx_helper_port_setup_ipd(int ipd_port)
0376 {
0377 union cvmx_pip_prt_cfgx port_config;
0378 union cvmx_pip_prt_tagx tag_config;
0379
0380 port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
0381 tag_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port));
0382
0383
0384 port_config.s.qos = ipd_port & 0x7;
0385
0386
0387 port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE;
0388
0389 tag_config.s.ip6_src_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP;
0390 tag_config.s.ip6_dst_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_IP;
0391 tag_config.s.ip6_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT;
0392 tag_config.s.ip6_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT;
0393 tag_config.s.ip6_nxth_flag = CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER;
0394 tag_config.s.ip4_src_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP;
0395 tag_config.s.ip4_dst_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_IP;
0396 tag_config.s.ip4_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT;
0397 tag_config.s.ip4_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT;
0398 tag_config.s.ip4_pctl_flag = CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL;
0399 tag_config.s.inc_prt_flag = CVMX_HELPER_INPUT_TAG_INPUT_PORT;
0400 tag_config.s.tcp6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
0401 tag_config.s.tcp4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
0402 tag_config.s.ip6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
0403 tag_config.s.ip4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
0404 tag_config.s.non_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
0405
0406 tag_config.s.grp = 0;
0407
0408 cvmx_pip_config_port(ipd_port, port_config, tag_config);
0409
0410 return 0;
0411 }
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422 int cvmx_helper_interface_enumerate(int interface)
0423 {
0424 switch (cvmx_helper_interface_get_mode(interface)) {
0425
0426 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
0427 case CVMX_HELPER_INTERFACE_MODE_PCIE:
0428 interface_port_count[interface] = 0;
0429 break;
0430
0431 case CVMX_HELPER_INTERFACE_MODE_XAUI:
0432 interface_port_count[interface] =
0433 __cvmx_helper_xaui_enumerate(interface);
0434 break;
0435
0436
0437
0438
0439 case CVMX_HELPER_INTERFACE_MODE_RGMII:
0440 case CVMX_HELPER_INTERFACE_MODE_GMII:
0441 interface_port_count[interface] =
0442 __cvmx_helper_rgmii_enumerate(interface);
0443 break;
0444
0445
0446
0447
0448 case CVMX_HELPER_INTERFACE_MODE_SPI:
0449 interface_port_count[interface] =
0450 __cvmx_helper_spi_enumerate(interface);
0451 break;
0452
0453
0454
0455
0456 case CVMX_HELPER_INTERFACE_MODE_SGMII:
0457 case CVMX_HELPER_INTERFACE_MODE_PICMG:
0458 interface_port_count[interface] =
0459 __cvmx_helper_sgmii_enumerate(interface);
0460 break;
0461
0462 case CVMX_HELPER_INTERFACE_MODE_NPI:
0463 interface_port_count[interface] =
0464 __cvmx_helper_npi_enumerate(interface);
0465 break;
0466
0467
0468
0469
0470 case CVMX_HELPER_INTERFACE_MODE_LOOP:
0471 interface_port_count[interface] =
0472 __cvmx_helper_loop_enumerate(interface);
0473 break;
0474 }
0475
0476 interface_port_count[interface] =
0477 __cvmx_helper_board_interface_probe(interface,
0478 interface_port_count
0479 [interface]);
0480
0481
0482 CVMX_SYNCWS;
0483
0484 return 0;
0485 }
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498 int cvmx_helper_interface_probe(int interface)
0499 {
0500 cvmx_helper_interface_enumerate(interface);
0501
0502
0503
0504 switch (cvmx_helper_interface_get_mode(interface)) {
0505
0506 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
0507 case CVMX_HELPER_INTERFACE_MODE_PCIE:
0508 break;
0509
0510 case CVMX_HELPER_INTERFACE_MODE_XAUI:
0511 __cvmx_helper_xaui_probe(interface);
0512 break;
0513
0514
0515
0516
0517 case CVMX_HELPER_INTERFACE_MODE_RGMII:
0518 case CVMX_HELPER_INTERFACE_MODE_GMII:
0519 __cvmx_helper_rgmii_probe(interface);
0520 break;
0521
0522
0523
0524
0525 case CVMX_HELPER_INTERFACE_MODE_SPI:
0526 __cvmx_helper_spi_probe(interface);
0527 break;
0528
0529
0530
0531
0532 case CVMX_HELPER_INTERFACE_MODE_SGMII:
0533 case CVMX_HELPER_INTERFACE_MODE_PICMG:
0534 __cvmx_helper_sgmii_probe(interface);
0535 break;
0536
0537 case CVMX_HELPER_INTERFACE_MODE_NPI:
0538 __cvmx_helper_npi_probe(interface);
0539 break;
0540
0541
0542
0543
0544 case CVMX_HELPER_INTERFACE_MODE_LOOP:
0545 __cvmx_helper_loop_probe(interface);
0546 break;
0547 }
0548
0549
0550 CVMX_SYNCWS;
0551
0552 return 0;
0553 }
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565 static int __cvmx_helper_interface_setup_ipd(int interface)
0566 {
0567 int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
0568 int num_ports = interface_port_count[interface];
0569
0570 while (num_ports--) {
0571 __cvmx_helper_port_setup_ipd(ipd_port);
0572 ipd_port++;
0573 }
0574 return 0;
0575 }
0576
0577
0578
0579
0580
0581
0582
0583 static int __cvmx_helper_global_setup_ipd(void)
0584 {
0585
0586 cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE / 8,
0587 CVMX_HELPER_FIRST_MBUFF_SKIP / 8,
0588 CVMX_HELPER_NOT_FIRST_MBUFF_SKIP / 8,
0589
0590 (CVMX_HELPER_FIRST_MBUFF_SKIP + 8) / 128,
0591
0592 (CVMX_HELPER_NOT_FIRST_MBUFF_SKIP + 8) / 128,
0593 CVMX_FPA_WQE_POOL,
0594 CVMX_IPD_OPC_MODE_STT,
0595 CVMX_HELPER_ENABLE_BACK_PRESSURE);
0596 return 0;
0597 }
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608 static int __cvmx_helper_interface_setup_pko(int interface)
0609 {
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622 uint64_t priorities[16] =
0623 { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 };
0624
0625
0626
0627
0628
0629
0630 int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
0631 int num_ports = interface_port_count[interface];
0632 while (num_ports--) {
0633 cvmx_pko_config_port(ipd_port,
0634 cvmx_pko_get_base_queue_per_core(ipd_port,
0635 0),
0636 cvmx_pko_get_num_queues(ipd_port),
0637 priorities);
0638 ipd_port++;
0639 }
0640 return 0;
0641 }
0642
0643
0644
0645
0646
0647
0648
0649 static int __cvmx_helper_global_setup_pko(void)
0650 {
0651
0652
0653
0654
0655 union cvmx_iob_fau_timeout fau_to;
0656 fau_to.u64 = 0;
0657 fau_to.s.tout_val = 0xfff;
0658 fau_to.s.tout_enb = 0;
0659 cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64);
0660
0661 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
0662 union cvmx_pko_reg_min_pkt min_pkt;
0663
0664 min_pkt.u64 = 0;
0665 min_pkt.s.size1 = 59;
0666 min_pkt.s.size2 = 59;
0667 min_pkt.s.size3 = 59;
0668 min_pkt.s.size4 = 59;
0669 min_pkt.s.size5 = 59;
0670 min_pkt.s.size6 = 59;
0671 min_pkt.s.size7 = 59;
0672 cvmx_write_csr(CVMX_PKO_REG_MIN_PKT, min_pkt.u64);
0673 }
0674
0675 return 0;
0676 }
0677
0678
0679
0680
0681
0682
0683 static int __cvmx_helper_global_setup_backpressure(void)
0684 {
0685 #if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE
0686
0687
0688 int num_interfaces = cvmx_helper_get_number_of_interfaces();
0689 int interface;
0690 for (interface = 0; interface < num_interfaces; interface++) {
0691 switch (cvmx_helper_interface_get_mode(interface)) {
0692 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
0693 case CVMX_HELPER_INTERFACE_MODE_PCIE:
0694 case CVMX_HELPER_INTERFACE_MODE_NPI:
0695 case CVMX_HELPER_INTERFACE_MODE_LOOP:
0696 case CVMX_HELPER_INTERFACE_MODE_XAUI:
0697 break;
0698 case CVMX_HELPER_INTERFACE_MODE_RGMII:
0699 case CVMX_HELPER_INTERFACE_MODE_GMII:
0700 case CVMX_HELPER_INTERFACE_MODE_SPI:
0701 case CVMX_HELPER_INTERFACE_MODE_SGMII:
0702 case CVMX_HELPER_INTERFACE_MODE_PICMG:
0703 cvmx_gmx_set_backpressure_override(interface, 0xf);
0704 break;
0705 }
0706 }
0707 #endif
0708
0709 return 0;
0710 }
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723 static int __cvmx_helper_packet_hardware_enable(int interface)
0724 {
0725 int result = 0;
0726 switch (cvmx_helper_interface_get_mode(interface)) {
0727
0728 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
0729 case CVMX_HELPER_INTERFACE_MODE_PCIE:
0730
0731 break;
0732
0733 case CVMX_HELPER_INTERFACE_MODE_XAUI:
0734 result = __cvmx_helper_xaui_enable(interface);
0735 break;
0736
0737
0738
0739
0740 case CVMX_HELPER_INTERFACE_MODE_RGMII:
0741 case CVMX_HELPER_INTERFACE_MODE_GMII:
0742 result = __cvmx_helper_rgmii_enable(interface);
0743 break;
0744
0745
0746
0747
0748 case CVMX_HELPER_INTERFACE_MODE_SPI:
0749 result = __cvmx_helper_spi_enable(interface);
0750 break;
0751
0752
0753
0754
0755 case CVMX_HELPER_INTERFACE_MODE_SGMII:
0756 case CVMX_HELPER_INTERFACE_MODE_PICMG:
0757 result = __cvmx_helper_sgmii_enable(interface);
0758 break;
0759
0760 case CVMX_HELPER_INTERFACE_MODE_NPI:
0761 result = __cvmx_helper_npi_enable(interface);
0762 break;
0763
0764
0765
0766
0767 case CVMX_HELPER_INTERFACE_MODE_LOOP:
0768 result = __cvmx_helper_loop_enable(interface);
0769 break;
0770 }
0771 return result;
0772 }
0773
0774
0775
0776
0777
0778
0779
0780 static int __cvmx_helper_errata_fix_ipd_ptr_alignment(void)
0781 {
0782 #define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \
0783 (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_FIRST_MBUFF_SKIP)
0784 #define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \
0785 (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_NOT_FIRST_MBUFF_SKIP)
0786 #define FIX_IPD_OUTPORT 0
0787
0788 #define INTERFACE(port) (port >> 4)
0789 #define INDEX(port) (port & 0xf)
0790 uint64_t *p64;
0791 union cvmx_pko_command_word0 pko_command;
0792 union cvmx_buf_ptr g_buffer, pkt_buffer;
0793 struct cvmx_wqe *work;
0794 int size, num_segs = 0, wqe_pcnt, pkt_pcnt;
0795 union cvmx_gmxx_prtx_cfg gmx_cfg;
0796 int retry_cnt;
0797 int retry_loop_cnt;
0798 int i;
0799
0800
0801 uint64_t prtx_cfg =
0802 cvmx_read_csr(CVMX_GMXX_PRTX_CFG
0803 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
0804 uint64_t tx_ptr_en =
0805 cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
0806 uint64_t rx_ptr_en =
0807 cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
0808 uint64_t rxx_jabber =
0809 cvmx_read_csr(CVMX_GMXX_RXX_JABBER
0810 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
0811 uint64_t frame_max =
0812 cvmx_read_csr(CVMX_GMXX_RXX_FRM_MAX
0813 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
0814
0815
0816 cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT);
0817
0818
0819
0820
0821
0822 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 0);
0823
0824 __delay(100000000ull);
0825
0826 for (retry_loop_cnt = 0; retry_loop_cnt < 10; retry_loop_cnt++) {
0827 retry_cnt = 100000;
0828 wqe_pcnt = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
0829 pkt_pcnt = (wqe_pcnt >> 7) & 0x7f;
0830 wqe_pcnt &= 0x7f;
0831
0832 num_segs = (2 + pkt_pcnt - wqe_pcnt) & 3;
0833
0834 if (num_segs == 0)
0835 goto fix_ipd_exit;
0836
0837 num_segs += 1;
0838
0839 size =
0840 FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES +
0841 ((num_segs - 1) * FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES) -
0842 (FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES / 2);
0843
0844 cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)),
0845 1 << INDEX(FIX_IPD_OUTPORT));
0846 CVMX_SYNC;
0847
0848 g_buffer.u64 = 0;
0849 g_buffer.s.addr =
0850 cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_WQE_POOL));
0851 if (g_buffer.s.addr == 0) {
0852 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
0853 "buffer allocation failure.\n");
0854 goto fix_ipd_exit;
0855 }
0856
0857 g_buffer.s.pool = CVMX_FPA_WQE_POOL;
0858 g_buffer.s.size = num_segs;
0859
0860 pkt_buffer.u64 = 0;
0861 pkt_buffer.s.addr =
0862 cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL));
0863 if (pkt_buffer.s.addr == 0) {
0864 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
0865 "buffer allocation failure.\n");
0866 goto fix_ipd_exit;
0867 }
0868 pkt_buffer.s.i = 1;
0869 pkt_buffer.s.pool = CVMX_FPA_PACKET_POOL;
0870 pkt_buffer.s.size = FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES;
0871
0872 p64 = (uint64_t *) cvmx_phys_to_ptr(pkt_buffer.s.addr);
0873 p64[0] = 0xffffffffffff0000ull;
0874 p64[1] = 0x08004510ull;
0875 p64[2] = ((uint64_t) (size - 14) << 48) | 0x5ae740004000ull;
0876 p64[3] = 0x3a5fc0a81073c0a8ull;
0877
0878 for (i = 0; i < num_segs; i++) {
0879 if (i > 0)
0880 pkt_buffer.s.size =
0881 FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES;
0882
0883 if (i == (num_segs - 1))
0884 pkt_buffer.s.i = 0;
0885
0886 *(uint64_t *) cvmx_phys_to_ptr(g_buffer.s.addr +
0887 8 * i) = pkt_buffer.u64;
0888 }
0889
0890
0891 pko_command.u64 = 0;
0892 pko_command.s.segs = num_segs;
0893 pko_command.s.total_bytes = size;
0894 pko_command.s.dontfree = 0;
0895 pko_command.s.gather = 1;
0896
0897 gmx_cfg.u64 =
0898 cvmx_read_csr(CVMX_GMXX_PRTX_CFG
0899 (INDEX(FIX_IPD_OUTPORT),
0900 INTERFACE(FIX_IPD_OUTPORT)));
0901 gmx_cfg.s.en = 1;
0902 cvmx_write_csr(CVMX_GMXX_PRTX_CFG
0903 (INDEX(FIX_IPD_OUTPORT),
0904 INTERFACE(FIX_IPD_OUTPORT)), gmx_cfg.u64);
0905 cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
0906 1 << INDEX(FIX_IPD_OUTPORT));
0907 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
0908 1 << INDEX(FIX_IPD_OUTPORT));
0909
0910 cvmx_write_csr(CVMX_GMXX_RXX_JABBER
0911 (INDEX(FIX_IPD_OUTPORT),
0912 INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
0913 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
0914 (INDEX(FIX_IPD_OUTPORT),
0915 INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
0916
0917 cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT,
0918 cvmx_pko_get_base_queue
0919 (FIX_IPD_OUTPORT),
0920 CVMX_PKO_LOCK_CMD_QUEUE);
0921 cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT,
0922 cvmx_pko_get_base_queue
0923 (FIX_IPD_OUTPORT), pko_command,
0924 g_buffer, CVMX_PKO_LOCK_CMD_QUEUE);
0925
0926 CVMX_SYNC;
0927
0928 do {
0929 work = cvmx_pow_work_request_sync(CVMX_POW_WAIT);
0930 retry_cnt--;
0931 } while ((work == NULL) && (retry_cnt > 0));
0932
0933 if (!retry_cnt)
0934 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
0935 "get_work() timeout occurred.\n");
0936
0937
0938 if (work)
0939 cvmx_helper_free_packet_data(work);
0940 }
0941
0942 fix_ipd_exit:
0943
0944
0945 cvmx_write_csr(CVMX_GMXX_PRTX_CFG
0946 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
0947 prtx_cfg);
0948 cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
0949 tx_ptr_en);
0950 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
0951 rx_ptr_en);
0952 cvmx_write_csr(CVMX_GMXX_RXX_JABBER
0953 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
0954 rxx_jabber);
0955 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
0956 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
0957 frame_max);
0958 cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0);
0959
0960 CVMX_SYNC;
0961 if (num_segs)
0962 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n");
0963
0964 return !!num_segs;
0965
0966 }
0967
0968
0969
0970
0971
0972
0973
0974 int cvmx_helper_ipd_and_packet_input_enable(void)
0975 {
0976 int num_interfaces;
0977 int interface;
0978
0979
0980 cvmx_ipd_enable();
0981
0982
0983
0984
0985
0986
0987 num_interfaces = cvmx_helper_get_number_of_interfaces();
0988 for (interface = 0; interface < num_interfaces; interface++) {
0989 if (cvmx_helper_ports_on_interface(interface) > 0)
0990 __cvmx_helper_packet_hardware_enable(interface);
0991 }
0992
0993
0994 cvmx_pko_enable();
0995
0996 if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1)
0997 || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1))
0998 && (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM))
0999 __cvmx_helper_errata_fix_ipd_ptr_alignment();
1000 return 0;
1001 }
1002 EXPORT_SYMBOL_GPL(cvmx_helper_ipd_and_packet_input_enable);
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013 int cvmx_helper_initialize_packet_io_global(void)
1014 {
1015 int result = 0;
1016 int interface;
1017 union cvmx_l2c_cfg l2c_cfg;
1018 const int num_interfaces = cvmx_helper_get_number_of_interfaces();
1019
1020
1021
1022
1023
1024 if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
1025 __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
1026
1027
1028
1029
1030
1031
1032 l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
1033 l2c_cfg.s.lrf_arb_mode = 0;
1034 l2c_cfg.s.rfb_arb_mode = 0;
1035 cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
1036
1037 cvmx_pko_initialize_global();
1038 for (interface = 0; interface < num_interfaces; interface++) {
1039 result |= cvmx_helper_interface_probe(interface);
1040 if (cvmx_helper_ports_on_interface(interface) > 0)
1041 cvmx_dprintf("Interface %d has %d ports (%s)\n",
1042 interface,
1043 cvmx_helper_ports_on_interface(interface),
1044 cvmx_helper_interface_mode_to_string
1045 (cvmx_helper_interface_get_mode
1046 (interface)));
1047 result |= __cvmx_helper_interface_setup_ipd(interface);
1048 result |= __cvmx_helper_interface_setup_pko(interface);
1049 }
1050
1051 result |= __cvmx_helper_global_setup_ipd();
1052 result |= __cvmx_helper_global_setup_pko();
1053
1054
1055 result |= __cvmx_helper_global_setup_backpressure();
1056
1057 #if CVMX_HELPER_ENABLE_IPD
1058 result |= cvmx_helper_ipd_and_packet_input_enable();
1059 #endif
1060 return result;
1061 }
1062 EXPORT_SYMBOL_GPL(cvmx_helper_initialize_packet_io_global);
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074 union cvmx_helper_link_info cvmx_helper_link_get(int ipd_port)
1075 {
1076 union cvmx_helper_link_info result;
1077 int interface = cvmx_helper_get_interface_num(ipd_port);
1078 int index = cvmx_helper_get_interface_index_num(ipd_port);
1079
1080
1081
1082 result.u64 = 0;
1083
1084 if (index >= cvmx_helper_ports_on_interface(interface))
1085 return result;
1086
1087 switch (cvmx_helper_interface_get_mode(interface)) {
1088 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
1089 case CVMX_HELPER_INTERFACE_MODE_PCIE:
1090
1091 break;
1092 case CVMX_HELPER_INTERFACE_MODE_XAUI:
1093 result = __cvmx_helper_xaui_link_get(ipd_port);
1094 break;
1095 case CVMX_HELPER_INTERFACE_MODE_GMII:
1096 if (index == 0)
1097 result = __cvmx_helper_rgmii_link_get(ipd_port);
1098 else {
1099 WARN(1, "Using deprecated link status - please update your DT");
1100 result.s.full_duplex = 1;
1101 result.s.link_up = 1;
1102 result.s.speed = 1000;
1103 }
1104 break;
1105 case CVMX_HELPER_INTERFACE_MODE_RGMII:
1106 result = __cvmx_helper_rgmii_link_get(ipd_port);
1107 break;
1108 case CVMX_HELPER_INTERFACE_MODE_SPI:
1109 result = __cvmx_helper_spi_link_get(ipd_port);
1110 break;
1111 case CVMX_HELPER_INTERFACE_MODE_SGMII:
1112 case CVMX_HELPER_INTERFACE_MODE_PICMG:
1113 result = __cvmx_helper_sgmii_link_get(ipd_port);
1114 break;
1115 case CVMX_HELPER_INTERFACE_MODE_NPI:
1116 case CVMX_HELPER_INTERFACE_MODE_LOOP:
1117
1118 break;
1119 }
1120 return result;
1121 }
1122 EXPORT_SYMBOL_GPL(cvmx_helper_link_get);
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135 int cvmx_helper_link_set(int ipd_port, union cvmx_helper_link_info link_info)
1136 {
1137 int result = -1;
1138 int interface = cvmx_helper_get_interface_num(ipd_port);
1139 int index = cvmx_helper_get_interface_index_num(ipd_port);
1140
1141 if (index >= cvmx_helper_ports_on_interface(interface))
1142 return -1;
1143
1144 switch (cvmx_helper_interface_get_mode(interface)) {
1145 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
1146 case CVMX_HELPER_INTERFACE_MODE_PCIE:
1147 break;
1148 case CVMX_HELPER_INTERFACE_MODE_XAUI:
1149 result = __cvmx_helper_xaui_link_set(ipd_port, link_info);
1150 break;
1151
1152
1153
1154
1155 case CVMX_HELPER_INTERFACE_MODE_RGMII:
1156 case CVMX_HELPER_INTERFACE_MODE_GMII:
1157 result = __cvmx_helper_rgmii_link_set(ipd_port, link_info);
1158 break;
1159 case CVMX_HELPER_INTERFACE_MODE_SPI:
1160 result = __cvmx_helper_spi_link_set(ipd_port, link_info);
1161 break;
1162 case CVMX_HELPER_INTERFACE_MODE_SGMII:
1163 case CVMX_HELPER_INTERFACE_MODE_PICMG:
1164 result = __cvmx_helper_sgmii_link_set(ipd_port, link_info);
1165 break;
1166 case CVMX_HELPER_INTERFACE_MODE_NPI:
1167 case CVMX_HELPER_INTERFACE_MODE_LOOP:
1168 break;
1169 }
1170 return result;
1171 }
1172 EXPORT_SYMBOL_GPL(cvmx_helper_link_set);