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
0034 #include <asm/octeon/octeon.h>
0035
0036 #include <asm/octeon/cvmx-config.h>
0037
0038 #include <asm/octeon/cvmx-helper.h>
0039
0040 #include <asm/octeon/cvmx-pko-defs.h>
0041 #include <asm/octeon/cvmx-gmxx-defs.h>
0042 #include <asm/octeon/cvmx-pcsx-defs.h>
0043 #include <asm/octeon/cvmx-pcsxx-defs.h>
0044
0045 int __cvmx_helper_xaui_enumerate(int interface)
0046 {
0047 union cvmx_gmxx_hg2_control gmx_hg2_control;
0048
0049
0050 gmx_hg2_control.u64 = cvmx_read_csr(CVMX_GMXX_HG2_CONTROL(interface));
0051 if (gmx_hg2_control.s.hg2tx_en)
0052 return 16;
0053 else
0054 return 1;
0055 }
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 int __cvmx_helper_xaui_probe(int interface)
0067 {
0068 int i;
0069 union cvmx_gmxx_inf_mode mode;
0070
0071
0072
0073
0074
0075
0076 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
0077 mode.s.en = 1;
0078 cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
0079
0080 __cvmx_helper_setup_gmx(interface, 1);
0081
0082
0083
0084
0085
0086
0087
0088 for (i = 0; i < 16; i++) {
0089 union cvmx_pko_mem_port_ptrs pko_mem_port_ptrs;
0090 pko_mem_port_ptrs.u64 = 0;
0091
0092
0093
0094
0095 pko_mem_port_ptrs.s.static_p = 0;
0096 pko_mem_port_ptrs.s.qos_mask = 0xff;
0097
0098 pko_mem_port_ptrs.s.eid = interface * 4;
0099 pko_mem_port_ptrs.s.pid = interface * 16 + i;
0100 cvmx_write_csr(CVMX_PKO_MEM_PORT_PTRS, pko_mem_port_ptrs.u64);
0101 }
0102 return __cvmx_helper_xaui_enumerate(interface);
0103 }
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 int __cvmx_helper_xaui_enable(int interface)
0115 {
0116 union cvmx_gmxx_prtx_cfg gmx_cfg;
0117 union cvmx_pcsxx_control1_reg xauiCtl;
0118 union cvmx_pcsxx_misc_ctl_reg xauiMiscCtl;
0119 union cvmx_gmxx_tx_xaui_ctl gmxXauiTxCtl;
0120 union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
0121 union cvmx_gmxx_tx_int_en gmx_tx_int_en;
0122 union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;
0123
0124
0125 if (octeon_has_feature(OCTEON_FEATURE_PKND)) {
0126 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
0127 gmx_cfg.s.pknd = cvmx_helper_get_ipd_port(interface, 0);
0128 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
0129 }
0130
0131
0132
0133
0134 xauiMiscCtl.u64 = cvmx_read_csr(CVMX_PCSXX_MISC_CTL_REG(interface));
0135 xauiMiscCtl.s.gmxeno = 1;
0136 cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
0137
0138
0139 gmx_rx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_EN(0, interface));
0140 cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0);
0141 gmx_tx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_TX_INT_EN(interface));
0142 cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0);
0143 pcsx_int_en_reg.u64 = cvmx_read_csr(CVMX_PCSXX_INT_EN_REG(interface));
0144 cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0);
0145
0146
0147
0148
0149 gmxXauiTxCtl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
0150
0151 gmxXauiTxCtl.s.dic_en = 1;
0152 gmxXauiTxCtl.s.uni_en = 0;
0153 cvmx_write_csr(CVMX_GMXX_TX_XAUI_CTL(interface), gmxXauiTxCtl.u64);
0154
0155
0156 xauiCtl.u64 = cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
0157 xauiCtl.s.lo_pwr = 0;
0158
0159
0160 if (!OCTEON_IS_MODEL(OCTEON_CN66XX) &&
0161 !OCTEON_IS_MODEL(OCTEON_CN68XX_PASS1_X) &&
0162 !OCTEON_IS_MODEL(OCTEON_CN68XX_PASS2_X))
0163 xauiCtl.s.reset = 1;
0164
0165 cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface), xauiCtl.u64);
0166
0167
0168 if (CVMX_WAIT_FOR_FIELD64
0169 (CVMX_PCSXX_CONTROL1_REG(interface), union cvmx_pcsxx_control1_reg,
0170 reset, ==, 0, 10000))
0171 return -1;
0172
0173 if (CVMX_WAIT_FOR_FIELD64
0174 (CVMX_PCSXX_10GBX_STATUS_REG(interface),
0175 union cvmx_pcsxx_10gbx_status_reg, alignd, ==, 1, 10000))
0176 return -1;
0177
0178 if (CVMX_WAIT_FOR_FIELD64
0179 (CVMX_GMXX_RX_XAUI_CTL(interface), union cvmx_gmxx_rx_xaui_ctl,
0180 status, ==, 0, 10000))
0181 return -1;
0182
0183
0184 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
0185 gmx_cfg.s.en = 0;
0186 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
0187
0188
0189 if (CVMX_WAIT_FOR_FIELD64
0190 (CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg,
0191 rx_idle, ==, 1, 10000))
0192 return -1;
0193
0194 if (CVMX_WAIT_FOR_FIELD64
0195 (CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg,
0196 tx_idle, ==, 1, 10000))
0197 return -1;
0198
0199
0200 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
0201 gmx_cfg.s.speed = 1;
0202 gmx_cfg.s.speed_msb = 0;
0203 gmx_cfg.s.slottime = 1;
0204 cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), 1);
0205 cvmx_write_csr(CVMX_GMXX_TXX_SLOT(0, interface), 512);
0206 cvmx_write_csr(CVMX_GMXX_TXX_BURST(0, interface), 8192);
0207 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
0208
0209
0210 cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(0, interface),
0211 cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(0, interface)));
0212 cvmx_write_csr(CVMX_GMXX_TX_INT_REG(interface),
0213 cvmx_read_csr(CVMX_GMXX_TX_INT_REG(interface)));
0214 cvmx_write_csr(CVMX_PCSXX_INT_REG(interface),
0215 cvmx_read_csr(CVMX_PCSXX_INT_REG(interface)));
0216
0217
0218 if (CVMX_WAIT_FOR_FIELD64
0219 (CVMX_PCSXX_STATUS1_REG(interface), union cvmx_pcsxx_status1_reg,
0220 rcv_lnk, ==, 1, 10000))
0221 return -1;
0222 if (CVMX_WAIT_FOR_FIELD64
0223 (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
0224 xmtflt, ==, 0, 10000))
0225 return -1;
0226 if (CVMX_WAIT_FOR_FIELD64
0227 (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
0228 rcvflt, ==, 0, 10000))
0229 return -1;
0230
0231 cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), gmx_rx_int_en.u64);
0232 cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64);
0233 cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), pcsx_int_en_reg.u64);
0234
0235
0236 xauiMiscCtl.s.gmxeno = 0;
0237 cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
0238
0239 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
0240 gmx_cfg.s.en = 1;
0241 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
0242
0243 __cvmx_interrupt_pcsx_intx_en_reg_enable(0, interface);
0244 __cvmx_interrupt_pcsx_intx_en_reg_enable(1, interface);
0245 __cvmx_interrupt_pcsx_intx_en_reg_enable(2, interface);
0246 __cvmx_interrupt_pcsx_intx_en_reg_enable(3, interface);
0247 __cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
0248 __cvmx_interrupt_gmxx_enable(interface);
0249
0250 return 0;
0251 }
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263 union cvmx_helper_link_info __cvmx_helper_xaui_link_get(int ipd_port)
0264 {
0265 int interface = cvmx_helper_get_interface_num(ipd_port);
0266 union cvmx_gmxx_tx_xaui_ctl gmxx_tx_xaui_ctl;
0267 union cvmx_gmxx_rx_xaui_ctl gmxx_rx_xaui_ctl;
0268 union cvmx_pcsxx_status1_reg pcsxx_status1_reg;
0269 union cvmx_helper_link_info result;
0270
0271 gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
0272 gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface));
0273 pcsxx_status1_reg.u64 =
0274 cvmx_read_csr(CVMX_PCSXX_STATUS1_REG(interface));
0275 result.u64 = 0;
0276
0277
0278 if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0) &&
0279 (pcsxx_status1_reg.s.rcv_lnk == 1)) {
0280 result.s.link_up = 1;
0281 result.s.full_duplex = 1;
0282 result.s.speed = 10000;
0283 } else {
0284
0285 cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0);
0286 cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0);
0287 cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0);
0288 }
0289 return result;
0290 }
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303 int __cvmx_helper_xaui_link_set(int ipd_port, union cvmx_helper_link_info link_info)
0304 {
0305 int interface = cvmx_helper_get_interface_num(ipd_port);
0306 union cvmx_gmxx_tx_xaui_ctl gmxx_tx_xaui_ctl;
0307 union cvmx_gmxx_rx_xaui_ctl gmxx_rx_xaui_ctl;
0308
0309 gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
0310 gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface));
0311
0312
0313 if (!link_info.s.link_up)
0314 return 0;
0315
0316
0317 if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0))
0318 return 0;
0319
0320
0321 return __cvmx_helper_xaui_enable(interface);
0322 }