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 #include <linux/kernel.h>
0032
0033 #include <asm/octeon/octeon.h>
0034
0035 #include <asm/octeon/cvmx-config.h>
0036
0037 #include <asm/octeon/cvmx-fpa.h>
0038 #include <asm/octeon/cvmx-pip.h>
0039 #include <asm/octeon/cvmx-pko.h>
0040 #include <asm/octeon/cvmx-ipd.h>
0041 #include <asm/octeon/cvmx-spi.h>
0042
0043 #include <asm/octeon/cvmx-helper.h>
0044 #include <asm/octeon/cvmx-helper-util.h>
0045
0046 #include <asm/octeon/cvmx-ipd-defs.h>
0047
0048
0049
0050
0051
0052
0053
0054
0055 const char *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t
0056 mode)
0057 {
0058 switch (mode) {
0059 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
0060 return "DISABLED";
0061 case CVMX_HELPER_INTERFACE_MODE_RGMII:
0062 return "RGMII";
0063 case CVMX_HELPER_INTERFACE_MODE_GMII:
0064 return "GMII";
0065 case CVMX_HELPER_INTERFACE_MODE_SPI:
0066 return "SPI";
0067 case CVMX_HELPER_INTERFACE_MODE_PCIE:
0068 return "PCIE";
0069 case CVMX_HELPER_INTERFACE_MODE_XAUI:
0070 return "XAUI";
0071 case CVMX_HELPER_INTERFACE_MODE_SGMII:
0072 return "SGMII";
0073 case CVMX_HELPER_INTERFACE_MODE_PICMG:
0074 return "PICMG";
0075 case CVMX_HELPER_INTERFACE_MODE_NPI:
0076 return "NPI";
0077 case CVMX_HELPER_INTERFACE_MODE_LOOP:
0078 return "LOOP";
0079 }
0080 return "UNKNOWN";
0081 }
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 static int cvmx_helper_setup_red_queue(int queue, int pass_thresh,
0096 int drop_thresh)
0097 {
0098 union cvmx_ipd_qosx_red_marks red_marks;
0099 union cvmx_ipd_red_quex_param red_param;
0100
0101
0102
0103
0104 red_marks.u64 = 0;
0105 red_marks.s.drop = drop_thresh;
0106 red_marks.s.pass = pass_thresh;
0107 cvmx_write_csr(CVMX_IPD_QOSX_RED_MARKS(queue), red_marks.u64);
0108
0109
0110 red_param.u64 = 0;
0111 red_param.s.prb_con =
0112 (255ul << 24) / (red_marks.s.pass - red_marks.s.drop);
0113 red_param.s.avg_con = 1;
0114 red_param.s.new_con = 255;
0115 red_param.s.use_pcnt = 1;
0116 cvmx_write_csr(CVMX_IPD_RED_QUEX_PARAM(queue), red_param.u64);
0117 return 0;
0118 }
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 int cvmx_helper_setup_red(int pass_thresh, int drop_thresh)
0132 {
0133 union cvmx_ipd_portx_bp_page_cnt page_cnt;
0134 union cvmx_ipd_bp_prt_red_end ipd_bp_prt_red_end;
0135 union cvmx_ipd_red_port_enable red_port_enable;
0136 int queue;
0137 int interface;
0138 int port;
0139
0140
0141 page_cnt.u64 = 0;
0142 page_cnt.s.bp_enb = 0;
0143 page_cnt.s.page_cnt = 100;
0144 for (interface = 0; interface < 2; interface++) {
0145 for (port = cvmx_helper_get_first_ipd_port(interface);
0146 port < cvmx_helper_get_last_ipd_port(interface); port++)
0147 cvmx_write_csr(CVMX_IPD_PORTX_BP_PAGE_CNT(port),
0148 page_cnt.u64);
0149 }
0150
0151 for (queue = 0; queue < 8; queue++)
0152 cvmx_helper_setup_red_queue(queue, pass_thresh, drop_thresh);
0153
0154
0155
0156 ipd_bp_prt_red_end.u64 = 0;
0157 ipd_bp_prt_red_end.s.prt_enb = 0;
0158 cvmx_write_csr(CVMX_IPD_BP_PRT_RED_END, ipd_bp_prt_red_end.u64);
0159
0160 red_port_enable.u64 = 0;
0161 red_port_enable.s.prt_enb = 0xfffffffffull;
0162 red_port_enable.s.avg_dly = 10000;
0163 red_port_enable.s.prb_dly = 10000;
0164 cvmx_write_csr(CVMX_IPD_RED_PORT_ENABLE, red_port_enable.u64);
0165
0166 return 0;
0167 }
0168 EXPORT_SYMBOL_GPL(cvmx_helper_setup_red);
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 int __cvmx_helper_setup_gmx(int interface, int num_ports)
0181 {
0182 union cvmx_gmxx_tx_prts gmx_tx_prts;
0183 union cvmx_gmxx_rx_prts gmx_rx_prts;
0184 union cvmx_pko_reg_gmx_port_mode pko_mode;
0185 union cvmx_gmxx_txx_thresh gmx_tx_thresh;
0186 int index;
0187
0188
0189 gmx_tx_prts.u64 = cvmx_read_csr(CVMX_GMXX_TX_PRTS(interface));
0190 gmx_tx_prts.s.prts = num_ports;
0191 cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), gmx_tx_prts.u64);
0192
0193
0194
0195 if (cvmx_helper_interface_get_mode(interface) ==
0196 CVMX_HELPER_INTERFACE_MODE_RGMII
0197 || cvmx_helper_interface_get_mode(interface) ==
0198 CVMX_HELPER_INTERFACE_MODE_SGMII
0199 || cvmx_helper_interface_get_mode(interface) ==
0200 CVMX_HELPER_INTERFACE_MODE_GMII
0201 || cvmx_helper_interface_get_mode(interface) ==
0202 CVMX_HELPER_INTERFACE_MODE_XAUI) {
0203 if (num_ports > 4) {
0204 cvmx_dprintf("__cvmx_helper_setup_gmx: Illegal "
0205 "num_ports\n");
0206 return -1;
0207 }
0208
0209 gmx_rx_prts.u64 = cvmx_read_csr(CVMX_GMXX_RX_PRTS(interface));
0210 gmx_rx_prts.s.prts = num_ports;
0211 cvmx_write_csr(CVMX_GMXX_RX_PRTS(interface), gmx_rx_prts.u64);
0212 }
0213
0214
0215 if (!OCTEON_IS_MODEL(OCTEON_CN30XX) && !OCTEON_IS_MODEL(OCTEON_CN31XX)
0216 && !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
0217
0218 pko_mode.u64 = cvmx_read_csr(CVMX_PKO_REG_GMX_PORT_MODE);
0219 if (interface == 0) {
0220 if (num_ports == 1)
0221 pko_mode.s.mode0 = 4;
0222 else if (num_ports == 2)
0223 pko_mode.s.mode0 = 3;
0224 else if (num_ports <= 4)
0225 pko_mode.s.mode0 = 2;
0226 else if (num_ports <= 8)
0227 pko_mode.s.mode0 = 1;
0228 else
0229 pko_mode.s.mode0 = 0;
0230 } else {
0231 if (num_ports == 1)
0232 pko_mode.s.mode1 = 4;
0233 else if (num_ports == 2)
0234 pko_mode.s.mode1 = 3;
0235 else if (num_ports <= 4)
0236 pko_mode.s.mode1 = 2;
0237 else if (num_ports <= 8)
0238 pko_mode.s.mode1 = 1;
0239 else
0240 pko_mode.s.mode1 = 0;
0241 }
0242 cvmx_write_csr(CVMX_PKO_REG_GMX_PORT_MODE, pko_mode.u64);
0243 }
0244
0245
0246
0247
0248
0249
0250
0251
0252 gmx_tx_thresh.u64 = cvmx_read_csr(CVMX_GMXX_TXX_THRESH(0, interface));
0253 if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN31XX)
0254 || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
0255
0256 gmx_tx_thresh.s.cnt = 0x40;
0257 } else {
0258
0259 if (num_ports <= 1)
0260 gmx_tx_thresh.s.cnt = 0x100 / 1;
0261 else if (num_ports == 2)
0262 gmx_tx_thresh.s.cnt = 0x100 / 2;
0263 else
0264 gmx_tx_thresh.s.cnt = 0x100 / 4;
0265 }
0266
0267
0268
0269
0270 if (num_ports > 4)
0271 num_ports = 4;
0272 for (index = 0; index < num_ports; index++)
0273 cvmx_write_csr(CVMX_GMXX_TXX_THRESH(index, interface),
0274 gmx_tx_thresh.u64);
0275
0276 return 0;
0277 }
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288 int cvmx_helper_get_ipd_port(int interface, int port)
0289 {
0290 switch (interface) {
0291 case 0:
0292 return port;
0293 case 1:
0294 return port + 16;
0295 case 2:
0296 return port + 32;
0297 case 3:
0298 return port + 36;
0299 case 4:
0300 return port + 40;
0301 case 5:
0302 return port + 44;
0303 }
0304 return -1;
0305 }
0306 EXPORT_SYMBOL_GPL(cvmx_helper_get_ipd_port);
0307
0308
0309
0310
0311
0312
0313
0314
0315 int cvmx_helper_get_interface_num(int ipd_port)
0316 {
0317 if (ipd_port < 16)
0318 return 0;
0319 else if (ipd_port < 32)
0320 return 1;
0321 else if (ipd_port < 36)
0322 return 2;
0323 else if (ipd_port < 40)
0324 return 3;
0325 else if (ipd_port < 44)
0326 return 4;
0327 else if (ipd_port < 48)
0328 return 5;
0329 else
0330 cvmx_dprintf("cvmx_helper_get_interface_num: Illegal IPD "
0331 "port number\n");
0332
0333 return -1;
0334 }
0335 EXPORT_SYMBOL_GPL(cvmx_helper_get_interface_num);
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345 int cvmx_helper_get_interface_index_num(int ipd_port)
0346 {
0347 if (ipd_port < 32)
0348 return ipd_port & 15;
0349 else if (ipd_port < 36)
0350 return ipd_port & 3;
0351 else if (ipd_port < 40)
0352 return ipd_port & 3;
0353 else if (ipd_port < 44)
0354 return ipd_port & 3;
0355 else if (ipd_port < 48)
0356 return ipd_port & 3;
0357 else
0358 cvmx_dprintf("cvmx_helper_get_interface_index_num: "
0359 "Illegal IPD port number\n");
0360
0361 return -1;
0362 }
0363 EXPORT_SYMBOL_GPL(cvmx_helper_get_interface_index_num);