1 /***********************license start***************
2 * Author: Cavium Networks
4 * Contact: support@caviumnetworks.com
5 * This file is part of the OCTEON SDK
7 * Copyright (c) 2003-2008 Cavium Networks
9 * This file is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License, Version 2, as
11 * published by the Free Software Foundation.
13 * This file is distributed in the hope that it will be useful, but
14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16 * NONINFRINGEMENT. See the GNU General Public License for more
19 * You should have received a copy of the GNU General Public License
20 * along with this file; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 * or visit http://www.gnu.org/licenses/.
24 * This file may also be available under a different license from Cavium.
25 * Contact Cavium Networks for more information
26 ***********************license end**************************************/
30 * Helper functions for common, but complicated tasks.
33 #include <asm/octeon/octeon.h>
35 #include <asm/octeon/cvmx-config.h>
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>
45 #include <asm/octeon/cvmx-pip-defs.h>
46 #include <asm/octeon/cvmx-smix-defs.h>
47 #include <asm/octeon/cvmx-asxx-defs.h>
50 * cvmx_override_pko_queue_priority(int ipd_port, uint64_t
51 * priorities[16]) is a function pointer. It is meant to allow
52 * customization of the PKO queue priorities based on the port
53 * number. Users should set this pointer to a function before
54 * calling any cvmx-helper operations.
56 void (*cvmx_override_pko_queue_priority) (int pko_port,
57 uint64_t priorities[16]);
60 * cvmx_override_ipd_port_setup(int ipd_port) is a function
61 * pointer. It is meant to allow customization of the IPD port
62 * setup before packet input/output comes online. It is called
63 * after cvmx-helper does the default IPD configuration, but
64 * before IPD is enabled. Users should set this pointer to a
65 * function before calling any cvmx-helper operations.
67 void (*cvmx_override_ipd_port_setup) (int ipd_port);
69 /* Port count per interface */
70 static int interface_port_count[5];
72 /* Port last configured link info index by IPD/PKO port */
73 static cvmx_helper_link_info_t
74 port_link_info[CVMX_PIP_NUM_INPUT_PORTS];
77 * Return the number of interfaces the chip has. Each interface
78 * may have multiple ports. Most chips support two interfaces,
79 * but the CNX0XX and CNX1XX are exceptions. These only support
82 * Returns Number of interfaces on chip
84 int cvmx_helper_get_number_of_interfaces(void)
86 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
88 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
93 EXPORT_SYMBOL_GPL(cvmx_helper_get_number_of_interfaces);
96 * Return the number of ports on an interface. Depending on the
97 * chip and configuration, this can be 1-16. A value of 0
98 * specifies that the interface doesn't exist or isn't usable.
100 * @interface: Interface to get the port count for
102 * Returns Number of ports on interface. Can be Zero.
104 int cvmx_helper_ports_on_interface(int interface)
106 return interface_port_count[interface];
108 EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface);
112 * Return interface mode for CN68xx.
114 static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface)
116 union cvmx_mio_qlmx_cfg qlm_cfg;
119 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
120 /* QLM is disabled when QLM SPD is 15. */
121 if (qlm_cfg.s.qlm_spd == 15)
122 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
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;
129 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
133 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(interface));
134 /* QLM is disabled when QLM SPD is 15. */
135 if (qlm_cfg.s.qlm_spd == 15)
136 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
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;
143 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
145 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(3));
146 /* QLM is disabled when QLM SPD is 15. */
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;
154 return CVMX_HELPER_INTERFACE_MODE_NPI;
156 return CVMX_HELPER_INTERFACE_MODE_LOOP;
158 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
164 * Return interface mode for an Octeon II
166 static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)
168 union cvmx_gmxx_inf_mode mode;
170 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
171 return __cvmx_get_mode_cn68xx(interface);
174 return CVMX_HELPER_INTERFACE_MODE_NPI;
177 return CVMX_HELPER_INTERFACE_MODE_LOOP;
179 /* Only present in CN63XX & CN66XX Octeon model */
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;
187 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
188 union cvmx_mio_qlmx_cfg mio_qlm_cfg;
190 /* QLM2 is SGMII0 and QLM1 is SGMII1 */
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));
196 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
198 if (mio_qlm_cfg.s.qlm_spd == 15)
199 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
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;
206 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
207 } else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) {
208 union cvmx_mio_qlmx_cfg qlm_cfg;
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;
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;
225 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
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;
234 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
237 if (interface == 1 && OCTEON_IS_MODEL(OCTEON_CN63XX))
238 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
240 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
242 if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
243 switch (mode.cn63xx.mode) {
245 return CVMX_HELPER_INTERFACE_MODE_SGMII;
247 return CVMX_HELPER_INTERFACE_MODE_XAUI;
249 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
253 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
256 return CVMX_HELPER_INTERFACE_MODE_GMII;
258 return CVMX_HELPER_INTERFACE_MODE_RGMII;
263 * Get the operating mode of an interface. Depending on the Octeon
264 * chip and configuration, this function returns an enumeration
265 * of the type of packet I/O supported by an interface.
267 * @interface: Interface to probe
269 * Returns Mode of the interface. Unknown or unsupported interfaces return
272 cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
274 union cvmx_gmxx_inf_mode mode;
277 interface >= cvmx_helper_get_number_of_interfaces())
278 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
283 if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
284 return __cvmx_get_mode_octeon2(interface);
287 * Octeon and Octeon Plus models
290 return CVMX_HELPER_INTERFACE_MODE_NPI;
292 if (interface == 3) {
293 if (OCTEON_IS_MODEL(OCTEON_CN56XX)
294 || OCTEON_IS_MODEL(OCTEON_CN52XX))
295 return CVMX_HELPER_INTERFACE_MODE_LOOP;
297 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
301 && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5
302 && cvmx_sysinfo_get()->board_rev_major == 1) {
304 * Lie about interface type of CN3005 board. This
305 * board has a switch on port 1 like the other
306 * evaluation boards, but it is connected over RGMII
307 * instead of GMII. Report GMII mode so that the
308 * speed is forced to 1 Gbit full duplex. Other than
309 * some initial configuration (which does not use the
310 * output of this function) there is no difference in
311 * setup between GMII and RGMII modes.
313 return CVMX_HELPER_INTERFACE_MODE_GMII;
316 /* Interface 1 is always disabled on CN31XX and CN30XX */
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;
323 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
325 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
326 switch (mode.cn56xx.mode) {
328 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
330 return CVMX_HELPER_INTERFACE_MODE_XAUI;
332 return CVMX_HELPER_INTERFACE_MODE_SGMII;
334 return CVMX_HELPER_INTERFACE_MODE_PICMG;
336 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
340 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
343 if (OCTEON_IS_MODEL(OCTEON_CN38XX)
344 || OCTEON_IS_MODEL(OCTEON_CN58XX))
345 return CVMX_HELPER_INTERFACE_MODE_SPI;
347 return CVMX_HELPER_INTERFACE_MODE_GMII;
349 return CVMX_HELPER_INTERFACE_MODE_RGMII;
352 EXPORT_SYMBOL_GPL(cvmx_helper_interface_get_mode);
355 * Configure the IPD/PIP tagging and QoS options for a specific
356 * port. This function determines the POW work queue entry
357 * contents for a port. The setup performed here is controlled by
358 * the defines in executive-config.h.
360 * @ipd_port: Port to configure. This follows the IPD numbering, not the
361 * per interface numbering
363 * Returns Zero on success, negative on failure
365 static int __cvmx_helper_port_setup_ipd(int ipd_port)
367 union cvmx_pip_prt_cfgx port_config;
368 union cvmx_pip_prt_tagx tag_config;
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));
373 /* Have each port go to a different POW queue */
374 port_config.s.qos = ipd_port & 0x7;
376 /* Process the headers and place the IP header in the work queue */
377 port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE;
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 /* Put all packets in group 0. Other groups can be used by the app */
396 tag_config.s.grp = 0;
398 cvmx_pip_config_port(ipd_port, port_config, tag_config);
400 /* Give the user a chance to override our setting for each port */
401 if (cvmx_override_ipd_port_setup)
402 cvmx_override_ipd_port_setup(ipd_port);
408 * This function sets the interface_port_count[interface] correctly,
409 * without modifying any hardware configuration. Hardware setup of
410 * the ports will be performed later.
412 * @interface: Interface to probe
414 * Returns Zero on success, negative on failure
416 int cvmx_helper_interface_enumerate(int interface)
418 switch (cvmx_helper_interface_get_mode(interface)) {
419 /* These types don't support ports to IPD/PKO */
420 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
421 case CVMX_HELPER_INTERFACE_MODE_PCIE:
422 interface_port_count[interface] = 0;
424 /* XAUI is a single high speed port */
425 case CVMX_HELPER_INTERFACE_MODE_XAUI:
426 interface_port_count[interface] =
427 __cvmx_helper_xaui_enumerate(interface);
430 * RGMII/GMII/MII are all treated about the same. Most
431 * functions refer to these ports as RGMII.
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);
439 * SPI4 can have 1-16 ports depending on the device at
442 case CVMX_HELPER_INTERFACE_MODE_SPI:
443 interface_port_count[interface] =
444 __cvmx_helper_spi_enumerate(interface);
447 * SGMII can have 1-4 ports depending on how many are
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);
455 /* PCI target Network Packet Interface */
456 case CVMX_HELPER_INTERFACE_MODE_NPI:
457 interface_port_count[interface] =
458 __cvmx_helper_npi_enumerate(interface);
461 * Special loopback only ports. These are not the same
462 * as other ports in loopback mode.
464 case CVMX_HELPER_INTERFACE_MODE_LOOP:
465 interface_port_count[interface] =
466 __cvmx_helper_loop_enumerate(interface);
470 interface_port_count[interface] =
471 __cvmx_helper_board_interface_probe(interface,
475 /* Make sure all global variables propagate to other cores */
482 * This function probes an interface to determine the actual
483 * number of hardware ports connected to it. It doesn't setup the
484 * ports or enable them. The main goal here is to set the global
485 * interface_port_count[interface] correctly. Hardware setup of the
486 * ports will be performed later.
488 * @interface: Interface to probe
490 * Returns Zero on success, negative on failure
492 int cvmx_helper_interface_probe(int interface)
494 cvmx_helper_interface_enumerate(interface);
495 /* At this stage in the game we don't want packets to be moving yet.
496 The following probe calls should perform hardware setup
497 needed to determine port counts. Receive must still be disabled */
498 switch (cvmx_helper_interface_get_mode(interface)) {
499 /* These types don't support ports to IPD/PKO */
500 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
501 case CVMX_HELPER_INTERFACE_MODE_PCIE:
503 /* XAUI is a single high speed port */
504 case CVMX_HELPER_INTERFACE_MODE_XAUI:
505 __cvmx_helper_xaui_probe(interface);
508 * RGMII/GMII/MII are all treated about the same. Most
509 * functions refer to these ports as RGMII.
511 case CVMX_HELPER_INTERFACE_MODE_RGMII:
512 case CVMX_HELPER_INTERFACE_MODE_GMII:
513 __cvmx_helper_rgmii_probe(interface);
516 * SPI4 can have 1-16 ports depending on the device at
519 case CVMX_HELPER_INTERFACE_MODE_SPI:
520 __cvmx_helper_spi_probe(interface);
523 * SGMII can have 1-4 ports depending on how many are
526 case CVMX_HELPER_INTERFACE_MODE_SGMII:
527 case CVMX_HELPER_INTERFACE_MODE_PICMG:
528 __cvmx_helper_sgmii_probe(interface);
530 /* PCI target Network Packet Interface */
531 case CVMX_HELPER_INTERFACE_MODE_NPI:
532 __cvmx_helper_npi_probe(interface);
535 * Special loopback only ports. These are not the same
536 * as other ports in loopback mode.
538 case CVMX_HELPER_INTERFACE_MODE_LOOP:
539 __cvmx_helper_loop_probe(interface);
543 /* Make sure all global variables propagate to other cores */
550 * Setup the IPD/PIP for the ports on an interface. Packet
551 * classification and tagging are set for every port on the
552 * interface. The number of ports on the interface must already
555 * @interface: Interface to setup IPD/PIP for
557 * Returns Zero on success, negative on failure
559 static int __cvmx_helper_interface_setup_ipd(int interface)
561 int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
562 int num_ports = interface_port_count[interface];
564 while (num_ports--) {
565 __cvmx_helper_port_setup_ipd(ipd_port);
572 * Setup global setting for IPD/PIP not related to a specific
573 * interface or port. This must be called before IPD is enabled.
575 * Returns Zero on success, negative on failure.
577 static int __cvmx_helper_global_setup_ipd(void)
579 /* Setup the global packet input options */
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 /* The +8 is to account for the next ptr */
584 (CVMX_HELPER_FIRST_MBUFF_SKIP + 8) / 128,
585 /* The +8 is to account for the next ptr */
586 (CVMX_HELPER_NOT_FIRST_MBUFF_SKIP + 8) / 128,
588 CVMX_IPD_OPC_MODE_STT,
589 CVMX_HELPER_ENABLE_BACK_PRESSURE);
594 * Setup the PKO for the ports on an interface. The number of
595 * queues per port and the priority of each PKO output queue
596 * is set here. PKO must be disabled when this function is called.
598 * @interface: Interface to setup PKO for
600 * Returns Zero on success, negative on failure
602 static int __cvmx_helper_interface_setup_pko(int interface)
605 * Each packet output queue has an associated priority. The
606 * higher the priority, the more often it can send a packet. A
607 * priority of 8 means it can send in all 8 rounds of
608 * contention. We're going to make each queue one less than
609 * the last. The vector of priorities has been extended to
610 * support CN5xxx CPUs, where up to 16 queues can be
611 * associated to a port. To keep backward compatibility we
612 * don't change the initial 8 priorities and replicate them in
613 * the second half. With per-core PKO queues (PKO lockless
614 * operation) all queues have the same priority.
616 uint64_t priorities[16] =
617 { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 };
620 * Setup the IPD/PIP and PKO for the ports discovered
621 * above. Here packet classification, tagging and output
622 * priorities are set.
624 int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
625 int num_ports = interface_port_count[interface];
626 while (num_ports--) {
628 * Give the user a chance to override the per queue
631 if (cvmx_override_pko_queue_priority)
632 cvmx_override_pko_queue_priority(ipd_port, priorities);
634 cvmx_pko_config_port(ipd_port,
635 cvmx_pko_get_base_queue_per_core(ipd_port,
637 cvmx_pko_get_num_queues(ipd_port),
645 * Setup global setting for PKO not related to a specific
646 * interface or port. This must be called before PKO is enabled.
648 * Returns Zero on success, negative on failure.
650 static int __cvmx_helper_global_setup_pko(void)
653 * Disable tagwait FAU timeout. This needs to be done before
654 * anyone might start packet output using tags.
656 union cvmx_iob_fau_timeout fau_to;
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);
665 * Setup global backpressure setting.
667 * Returns Zero on success, negative on failure
669 static int __cvmx_helper_global_setup_backpressure(void)
671 #if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE
672 /* Disable backpressure if configured to do so */
673 /* Disable backpressure (pause frame) generation */
674 int num_interfaces = cvmx_helper_get_number_of_interfaces();
676 for (interface = 0; interface < num_interfaces; interface++) {
677 switch (cvmx_helper_interface_get_mode(interface)) {
678 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
679 case CVMX_HELPER_INTERFACE_MODE_PCIE:
680 case CVMX_HELPER_INTERFACE_MODE_NPI:
681 case CVMX_HELPER_INTERFACE_MODE_LOOP:
682 case CVMX_HELPER_INTERFACE_MODE_XAUI:
684 case CVMX_HELPER_INTERFACE_MODE_RGMII:
685 case CVMX_HELPER_INTERFACE_MODE_GMII:
686 case CVMX_HELPER_INTERFACE_MODE_SPI:
687 case CVMX_HELPER_INTERFACE_MODE_SGMII:
688 case CVMX_HELPER_INTERFACE_MODE_PICMG:
689 cvmx_gmx_set_backpressure_override(interface, 0xf);
699 * Enable packet input/output from the hardware. This function is
700 * called after all internal setup is complete and IPD is enabled.
701 * After this function completes, packets will be accepted from the
702 * hardware ports. PKO should still be disabled to make sure packets
703 * aren't sent out partially setup hardware.
705 * @interface: Interface to enable
707 * Returns Zero on success, negative on failure
709 static int __cvmx_helper_packet_hardware_enable(int interface)
712 switch (cvmx_helper_interface_get_mode(interface)) {
713 /* These types don't support ports to IPD/PKO */
714 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
715 case CVMX_HELPER_INTERFACE_MODE_PCIE:
718 /* XAUI is a single high speed port */
719 case CVMX_HELPER_INTERFACE_MODE_XAUI:
720 result = __cvmx_helper_xaui_enable(interface);
723 * RGMII/GMII/MII are all treated about the same. Most
724 * functions refer to these ports as RGMII
726 case CVMX_HELPER_INTERFACE_MODE_RGMII:
727 case CVMX_HELPER_INTERFACE_MODE_GMII:
728 result = __cvmx_helper_rgmii_enable(interface);
731 * SPI4 can have 1-16 ports depending on the device at
734 case CVMX_HELPER_INTERFACE_MODE_SPI:
735 result = __cvmx_helper_spi_enable(interface);
738 * SGMII can have 1-4 ports depending on how many are
741 case CVMX_HELPER_INTERFACE_MODE_SGMII:
742 case CVMX_HELPER_INTERFACE_MODE_PICMG:
743 result = __cvmx_helper_sgmii_enable(interface);
745 /* PCI target Network Packet Interface */
746 case CVMX_HELPER_INTERFACE_MODE_NPI:
747 result = __cvmx_helper_npi_enable(interface);
750 * Special loopback only ports. These are not the same
751 * as other ports in loopback mode
753 case CVMX_HELPER_INTERFACE_MODE_LOOP:
754 result = __cvmx_helper_loop_enable(interface);
757 result |= __cvmx_helper_board_hardware_enable(interface);
762 * Function to adjust internal IPD pointer alignments
764 * Returns 0 on success
767 int __cvmx_helper_errata_fix_ipd_ptr_alignment(void)
769 #define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \
770 (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_FIRST_MBUFF_SKIP)
771 #define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \
772 (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_NOT_FIRST_MBUFF_SKIP)
773 #define FIX_IPD_OUTPORT 0
774 /* Ports 0-15 are interface 0, 16-31 are interface 1 */
775 #define INTERFACE(port) (port >> 4)
776 #define INDEX(port) (port & 0xf)
778 cvmx_pko_command_word0_t pko_command;
779 union cvmx_buf_ptr g_buffer, pkt_buffer;
781 int size, num_segs = 0, wqe_pcnt, pkt_pcnt;
782 union cvmx_gmxx_prtx_cfg gmx_cfg;
786 cvmx_helper_link_info_t link_info;
788 /* Save values for restore at end */
790 cvmx_read_csr(CVMX_GMXX_PRTX_CFG
791 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
793 cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
795 cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
796 uint64_t rxx_jabber =
797 cvmx_read_csr(CVMX_GMXX_RXX_JABBER
798 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
800 cvmx_read_csr(CVMX_GMXX_RXX_FRM_MAX
801 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
803 /* Configure port to gig FDX as required for loopback mode */
804 cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT);
807 * Disable reception on all ports so if traffic is present it
808 * will not interfere.
810 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 0);
812 cvmx_wait(100000000ull);
814 for (retry_loop_cnt = 0; retry_loop_cnt < 10; retry_loop_cnt++) {
816 wqe_pcnt = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
817 pkt_pcnt = (wqe_pcnt >> 7) & 0x7f;
820 num_segs = (2 + pkt_pcnt - wqe_pcnt) & 3;
828 FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES +
829 ((num_segs - 1) * FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES) -
830 (FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES / 2);
832 cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)),
833 1 << INDEX(FIX_IPD_OUTPORT));
838 cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_WQE_POOL));
839 if (g_buffer.s.addr == 0) {
840 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
841 "buffer allocation failure.\n");
845 g_buffer.s.pool = CVMX_FPA_WQE_POOL;
846 g_buffer.s.size = num_segs;
850 cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL));
851 if (pkt_buffer.s.addr == 0) {
852 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
853 "buffer allocation failure.\n");
857 pkt_buffer.s.pool = CVMX_FPA_PACKET_POOL;
858 pkt_buffer.s.size = FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES;
860 p64 = (uint64_t *) cvmx_phys_to_ptr(pkt_buffer.s.addr);
861 p64[0] = 0xffffffffffff0000ull;
862 p64[1] = 0x08004510ull;
863 p64[2] = ((uint64_t) (size - 14) << 48) | 0x5ae740004000ull;
864 p64[3] = 0x3a5fc0a81073c0a8ull;
866 for (i = 0; i < num_segs; i++) {
869 FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES;
871 if (i == (num_segs - 1))
874 *(uint64_t *) cvmx_phys_to_ptr(g_buffer.s.addr +
875 8 * i) = pkt_buffer.u64;
878 /* Build the PKO command */
880 pko_command.s.segs = num_segs;
881 pko_command.s.total_bytes = size;
882 pko_command.s.dontfree = 0;
883 pko_command.s.gather = 1;
886 cvmx_read_csr(CVMX_GMXX_PRTX_CFG
887 (INDEX(FIX_IPD_OUTPORT),
888 INTERFACE(FIX_IPD_OUTPORT)));
890 cvmx_write_csr(CVMX_GMXX_PRTX_CFG
891 (INDEX(FIX_IPD_OUTPORT),
892 INTERFACE(FIX_IPD_OUTPORT)), gmx_cfg.u64);
893 cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
894 1 << INDEX(FIX_IPD_OUTPORT));
895 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
896 1 << INDEX(FIX_IPD_OUTPORT));
898 cvmx_write_csr(CVMX_GMXX_RXX_JABBER
899 (INDEX(FIX_IPD_OUTPORT),
900 INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
901 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
902 (INDEX(FIX_IPD_OUTPORT),
903 INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
905 cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT,
906 cvmx_pko_get_base_queue
908 CVMX_PKO_LOCK_CMD_QUEUE);
909 cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT,
910 cvmx_pko_get_base_queue
911 (FIX_IPD_OUTPORT), pko_command,
912 g_buffer, CVMX_PKO_LOCK_CMD_QUEUE);
917 work = cvmx_pow_work_request_sync(CVMX_POW_WAIT);
919 } while ((work == NULL) && (retry_cnt > 0));
922 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
923 "get_work() timeout occurred.\n");
927 cvmx_helper_free_packet_data(work);
932 /* Return CSR configs to saved values */
933 cvmx_write_csr(CVMX_GMXX_PRTX_CFG
934 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
936 cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
938 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
940 cvmx_write_csr(CVMX_GMXX_RXX_JABBER
941 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
943 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
944 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
946 cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0);
947 /* Set link to down so autonegotiation will set it up again */
949 cvmx_helper_link_set(FIX_IPD_OUTPORT, link_info);
952 * Bring the link back up as autonegotiation is not done in
955 cvmx_helper_link_autoconf(FIX_IPD_OUTPORT);
959 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n");
966 * Called after all internal packet IO paths are setup. This
967 * function enables IPD/PIP and begins packet input and output.
969 * Returns Zero on success, negative on failure
971 int cvmx_helper_ipd_and_packet_input_enable(void)
980 * Time to enable hardware ports packet input and output. Note
981 * that at this point IPD/PIP must be fully functional and PKO
984 num_interfaces = cvmx_helper_get_number_of_interfaces();
985 for (interface = 0; interface < num_interfaces; interface++) {
986 if (cvmx_helper_ports_on_interface(interface) > 0)
987 __cvmx_helper_packet_hardware_enable(interface);
990 /* Finally enable PKO now that the entire path is up and running */
993 if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1)
994 || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1))
995 && (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM))
996 __cvmx_helper_errata_fix_ipd_ptr_alignment();
999 EXPORT_SYMBOL_GPL(cvmx_helper_ipd_and_packet_input_enable);
1002 * Initialize the PIP, IPD, and PKO hardware to support
1003 * simple priority based queues for the ethernet ports. Each
1004 * port is configured with a number of priority queues based
1005 * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
1006 * priority than the previous.
1008 * Returns Zero on success, non-zero on failure
1010 int cvmx_helper_initialize_packet_io_global(void)
1014 union cvmx_l2c_cfg l2c_cfg;
1015 union cvmx_smix_en smix_en;
1016 const int num_interfaces = cvmx_helper_get_number_of_interfaces();
1019 * CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to
1022 if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
1023 __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
1026 * Tell L2 to give the IOB statically higher priority compared
1027 * to the cores. This avoids conditions where IO blocks might
1028 * be starved under very high L2 loads.
1030 l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
1031 l2c_cfg.s.lrf_arb_mode = 0;
1032 l2c_cfg.s.rfb_arb_mode = 0;
1033 cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
1035 /* Make sure SMI/MDIO is enabled so we can query PHYs */
1036 smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0));
1037 if (!smix_en.s.en) {
1039 cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64);
1042 /* Newer chips actually have two SMI/MDIO interfaces */
1043 if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
1044 !OCTEON_IS_MODEL(OCTEON_CN58XX) &&
1045 !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
1046 smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1));
1047 if (!smix_en.s.en) {
1049 cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64);
1053 cvmx_pko_initialize_global();
1054 for (interface = 0; interface < num_interfaces; interface++) {
1055 result |= cvmx_helper_interface_probe(interface);
1056 if (cvmx_helper_ports_on_interface(interface) > 0)
1057 cvmx_dprintf("Interface %d has %d ports (%s)\n",
1059 cvmx_helper_ports_on_interface(interface),
1060 cvmx_helper_interface_mode_to_string
1061 (cvmx_helper_interface_get_mode
1063 result |= __cvmx_helper_interface_setup_ipd(interface);
1064 result |= __cvmx_helper_interface_setup_pko(interface);
1067 result |= __cvmx_helper_global_setup_ipd();
1068 result |= __cvmx_helper_global_setup_pko();
1070 /* Enable any flow control and backpressure */
1071 result |= __cvmx_helper_global_setup_backpressure();
1073 #if CVMX_HELPER_ENABLE_IPD
1074 result |= cvmx_helper_ipd_and_packet_input_enable();
1078 EXPORT_SYMBOL_GPL(cvmx_helper_initialize_packet_io_global);
1081 * Does core local initialization for packet io
1083 * Returns Zero on success, non-zero on failure
1085 int cvmx_helper_initialize_packet_io_local(void)
1087 return cvmx_pko_initialize_local();
1091 * Auto configure an IPD/PKO port link state and speed. This
1092 * function basically does the equivalent of:
1093 * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
1095 * @ipd_port: IPD/PKO port to auto configure
1097 * Returns Link state after configure
1099 cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port)
1101 cvmx_helper_link_info_t link_info;
1102 int interface = cvmx_helper_get_interface_num(ipd_port);
1103 int index = cvmx_helper_get_interface_index_num(ipd_port);
1105 if (index >= cvmx_helper_ports_on_interface(interface)) {
1110 link_info = cvmx_helper_link_get(ipd_port);
1111 if (link_info.u64 == port_link_info[ipd_port].u64)
1114 /* If we fail to set the link speed, port_link_info will not change */
1115 cvmx_helper_link_set(ipd_port, link_info);
1118 * port_link_info should be the current value, which will be
1119 * different than expect if cvmx_helper_link_set() failed.
1121 return port_link_info[ipd_port];
1123 EXPORT_SYMBOL_GPL(cvmx_helper_link_autoconf);
1126 * Return the link state of an IPD/PKO port as returned by
1127 * auto negotiation. The result of this function may not match
1128 * Octeon's link config if auto negotiation has changed since
1129 * the last call to cvmx_helper_link_set().
1131 * @ipd_port: IPD/PKO port to query
1133 * Returns Link state
1135 cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
1137 cvmx_helper_link_info_t result;
1138 int interface = cvmx_helper_get_interface_num(ipd_port);
1139 int index = cvmx_helper_get_interface_index_num(ipd_port);
1141 /* The default result will be a down link unless the code below
1145 if (index >= cvmx_helper_ports_on_interface(interface))
1148 switch (cvmx_helper_interface_get_mode(interface)) {
1149 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
1150 case CVMX_HELPER_INTERFACE_MODE_PCIE:
1151 /* Network links are not supported */
1153 case CVMX_HELPER_INTERFACE_MODE_XAUI:
1154 result = __cvmx_helper_xaui_link_get(ipd_port);
1156 case CVMX_HELPER_INTERFACE_MODE_GMII:
1158 result = __cvmx_helper_rgmii_link_get(ipd_port);
1160 result.s.full_duplex = 1;
1161 result.s.link_up = 1;
1162 result.s.speed = 1000;
1165 case CVMX_HELPER_INTERFACE_MODE_RGMII:
1166 result = __cvmx_helper_rgmii_link_get(ipd_port);
1168 case CVMX_HELPER_INTERFACE_MODE_SPI:
1169 result = __cvmx_helper_spi_link_get(ipd_port);
1171 case CVMX_HELPER_INTERFACE_MODE_SGMII:
1172 case CVMX_HELPER_INTERFACE_MODE_PICMG:
1173 result = __cvmx_helper_sgmii_link_get(ipd_port);
1175 case CVMX_HELPER_INTERFACE_MODE_NPI:
1176 case CVMX_HELPER_INTERFACE_MODE_LOOP:
1177 /* Network links are not supported */
1182 EXPORT_SYMBOL_GPL(cvmx_helper_link_get);
1185 * Configure an IPD/PKO port for the specified link state. This
1186 * function does not influence auto negotiation at the PHY level.
1187 * The passed link state must always match the link state returned
1188 * by cvmx_helper_link_get(). It is normally best to use
1189 * cvmx_helper_link_autoconf() instead.
1191 * @ipd_port: IPD/PKO port to configure
1192 * @link_info: The new link state
1194 * Returns Zero on success, negative on failure
1196 int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
1199 int interface = cvmx_helper_get_interface_num(ipd_port);
1200 int index = cvmx_helper_get_interface_index_num(ipd_port);
1202 if (index >= cvmx_helper_ports_on_interface(interface))
1205 switch (cvmx_helper_interface_get_mode(interface)) {
1206 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
1207 case CVMX_HELPER_INTERFACE_MODE_PCIE:
1209 case CVMX_HELPER_INTERFACE_MODE_XAUI:
1210 result = __cvmx_helper_xaui_link_set(ipd_port, link_info);
1213 * RGMII/GMII/MII are all treated about the same. Most
1214 * functions refer to these ports as RGMII.
1216 case CVMX_HELPER_INTERFACE_MODE_RGMII:
1217 case CVMX_HELPER_INTERFACE_MODE_GMII:
1218 result = __cvmx_helper_rgmii_link_set(ipd_port, link_info);
1220 case CVMX_HELPER_INTERFACE_MODE_SPI:
1221 result = __cvmx_helper_spi_link_set(ipd_port, link_info);
1223 case CVMX_HELPER_INTERFACE_MODE_SGMII:
1224 case CVMX_HELPER_INTERFACE_MODE_PICMG:
1225 result = __cvmx_helper_sgmii_link_set(ipd_port, link_info);
1227 case CVMX_HELPER_INTERFACE_MODE_NPI:
1228 case CVMX_HELPER_INTERFACE_MODE_LOOP:
1231 /* Set the port_link_info here so that the link status is updated
1232 no matter how cvmx_helper_link_set is called. We don't change
1233 the value if link_set failed */
1235 port_link_info[ipd_port].u64 = link_info.u64;
1238 EXPORT_SYMBOL_GPL(cvmx_helper_link_set);
1241 * Configure a port for internal and/or external loopback. Internal loopback
1242 * causes packets sent by the port to be received by Octeon. External loopback
1243 * causes packets received from the wire to sent out again.
1245 * @ipd_port: IPD/PKO port to loopback.
1247 * Non zero if you want internal loopback
1249 * Non zero if you want external loopback
1251 * Returns Zero on success, negative on failure.
1253 int cvmx_helper_configure_loopback(int ipd_port, int enable_internal,
1254 int enable_external)
1257 int interface = cvmx_helper_get_interface_num(ipd_port);
1258 int index = cvmx_helper_get_interface_index_num(ipd_port);
1260 if (index >= cvmx_helper_ports_on_interface(interface))
1263 switch (cvmx_helper_interface_get_mode(interface)) {
1264 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
1265 case CVMX_HELPER_INTERFACE_MODE_PCIE:
1266 case CVMX_HELPER_INTERFACE_MODE_SPI:
1267 case CVMX_HELPER_INTERFACE_MODE_NPI:
1268 case CVMX_HELPER_INTERFACE_MODE_LOOP:
1270 case CVMX_HELPER_INTERFACE_MODE_XAUI:
1272 __cvmx_helper_xaui_configure_loopback(ipd_port,
1276 case CVMX_HELPER_INTERFACE_MODE_RGMII:
1277 case CVMX_HELPER_INTERFACE_MODE_GMII:
1279 __cvmx_helper_rgmii_configure_loopback(ipd_port,
1283 case CVMX_HELPER_INTERFACE_MODE_SGMII:
1284 case CVMX_HELPER_INTERFACE_MODE_PICMG:
1286 __cvmx_helper_sgmii_configure_loopback(ipd_port,