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 <linux/bug.h>
34 #include <asm/octeon/octeon.h>
36 #include <asm/octeon/cvmx-config.h>
38 #include <asm/octeon/cvmx-fpa.h>
39 #include <asm/octeon/cvmx-pip.h>
40 #include <asm/octeon/cvmx-pko.h>
41 #include <asm/octeon/cvmx-ipd.h>
42 #include <asm/octeon/cvmx-spi.h>
43 #include <asm/octeon/cvmx-helper.h>
44 #include <asm/octeon/cvmx-helper-board.h>
46 #include <asm/octeon/cvmx-pip-defs.h>
47 #include <asm/octeon/cvmx-asxx-defs.h>
49 /* Port count per interface */
50 static int interface_port_count
[9];
53 * Return the number of interfaces the chip has. Each interface
54 * may have multiple ports. Most chips support two interfaces,
55 * but the CNX0XX and CNX1XX are exceptions. These only support
58 * Returns Number of interfaces on chip
60 int cvmx_helper_get_number_of_interfaces(void)
62 if (OCTEON_IS_MODEL(OCTEON_CN68XX
))
64 if (OCTEON_IS_MODEL(OCTEON_CN66XX
)) {
65 if (OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_0
))
70 if (OCTEON_IS_MODEL(OCTEON_CN56XX
) || OCTEON_IS_MODEL(OCTEON_CN52XX
))
72 if (OCTEON_IS_MODEL(OCTEON_CN7XXX
))
77 EXPORT_SYMBOL_GPL(cvmx_helper_get_number_of_interfaces
);
80 * Return the number of ports on an interface. Depending on the
81 * chip and configuration, this can be 1-16. A value of 0
82 * specifies that the interface doesn't exist or isn't usable.
84 * @interface: Interface to get the port count for
86 * Returns Number of ports on interface. Can be Zero.
88 int cvmx_helper_ports_on_interface(int interface
)
90 return interface_port_count
[interface
];
92 EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface
);
96 * Return interface mode for CN68xx.
98 static cvmx_helper_interface_mode_t
__cvmx_get_mode_cn68xx(int interface
)
100 union cvmx_mio_qlmx_cfg qlm_cfg
;
103 qlm_cfg
.u64
= cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
104 /* QLM is disabled when QLM SPD is 15. */
105 if (qlm_cfg
.s
.qlm_spd
== 15)
106 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
108 if (qlm_cfg
.s
.qlm_cfg
== 2)
109 return CVMX_HELPER_INTERFACE_MODE_SGMII
;
110 else if (qlm_cfg
.s
.qlm_cfg
== 3)
111 return CVMX_HELPER_INTERFACE_MODE_XAUI
;
113 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
117 qlm_cfg
.u64
= cvmx_read_csr(CVMX_MIO_QLMX_CFG(interface
));
118 /* QLM is disabled when QLM SPD is 15. */
119 if (qlm_cfg
.s
.qlm_spd
== 15)
120 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
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
;
127 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
129 qlm_cfg
.u64
= cvmx_read_csr(CVMX_MIO_QLMX_CFG(3));
130 /* QLM is disabled when QLM SPD is 15. */
131 if (qlm_cfg
.s
.qlm_spd
== 15) {
132 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
133 } else if (qlm_cfg
.s
.qlm_cfg
!= 0) {
134 qlm_cfg
.u64
= cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
135 if (qlm_cfg
.s
.qlm_cfg
!= 0)
136 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
138 return CVMX_HELPER_INTERFACE_MODE_NPI
;
140 return CVMX_HELPER_INTERFACE_MODE_LOOP
;
142 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
148 * Return interface mode for an Octeon II
150 static cvmx_helper_interface_mode_t
__cvmx_get_mode_octeon2(int interface
)
152 union cvmx_gmxx_inf_mode mode
;
154 if (OCTEON_IS_MODEL(OCTEON_CN68XX
))
155 return __cvmx_get_mode_cn68xx(interface
);
158 return CVMX_HELPER_INTERFACE_MODE_NPI
;
161 return CVMX_HELPER_INTERFACE_MODE_LOOP
;
163 /* Only present in CN63XX & CN66XX Octeon model */
164 if ((OCTEON_IS_MODEL(OCTEON_CN63XX
) &&
165 (interface
== 4 || interface
== 5)) ||
166 (OCTEON_IS_MODEL(OCTEON_CN66XX
) &&
167 interface
>= 4 && interface
<= 7)) {
168 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
171 if (OCTEON_IS_MODEL(OCTEON_CN66XX
)) {
172 union cvmx_mio_qlmx_cfg mio_qlm_cfg
;
174 /* QLM2 is SGMII0 and QLM1 is SGMII1 */
176 mio_qlm_cfg
.u64
= cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
177 else if (interface
== 1)
178 mio_qlm_cfg
.u64
= cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
180 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
182 if (mio_qlm_cfg
.s
.qlm_spd
== 15)
183 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
185 if (mio_qlm_cfg
.s
.qlm_cfg
== 9)
186 return CVMX_HELPER_INTERFACE_MODE_SGMII
;
187 else if (mio_qlm_cfg
.s
.qlm_cfg
== 11)
188 return CVMX_HELPER_INTERFACE_MODE_XAUI
;
190 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
191 } else if (OCTEON_IS_MODEL(OCTEON_CN61XX
)) {
192 union cvmx_mio_qlmx_cfg qlm_cfg
;
194 if (interface
== 0) {
195 qlm_cfg
.u64
= cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
196 if (qlm_cfg
.s
.qlm_cfg
== 2)
197 return CVMX_HELPER_INTERFACE_MODE_SGMII
;
198 else if (qlm_cfg
.s
.qlm_cfg
== 3)
199 return CVMX_HELPER_INTERFACE_MODE_XAUI
;
201 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
202 } else if (interface
== 1) {
203 qlm_cfg
.u64
= cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
204 if (qlm_cfg
.s
.qlm_cfg
== 2)
205 return CVMX_HELPER_INTERFACE_MODE_SGMII
;
206 else if (qlm_cfg
.s
.qlm_cfg
== 3)
207 return CVMX_HELPER_INTERFACE_MODE_XAUI
;
209 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
211 } else if (OCTEON_IS_MODEL(OCTEON_CNF71XX
)) {
212 if (interface
== 0) {
213 union cvmx_mio_qlmx_cfg qlm_cfg
;
214 qlm_cfg
.u64
= cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
215 if (qlm_cfg
.s
.qlm_cfg
== 2)
216 return CVMX_HELPER_INTERFACE_MODE_SGMII
;
218 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
221 if (interface
== 1 && OCTEON_IS_MODEL(OCTEON_CN63XX
))
222 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
224 mode
.u64
= cvmx_read_csr(CVMX_GMXX_INF_MODE(interface
));
226 if (OCTEON_IS_MODEL(OCTEON_CN63XX
)) {
227 switch (mode
.cn61xx
.mode
) {
229 return CVMX_HELPER_INTERFACE_MODE_SGMII
;
231 return CVMX_HELPER_INTERFACE_MODE_XAUI
;
233 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
237 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
240 return CVMX_HELPER_INTERFACE_MODE_GMII
;
242 return CVMX_HELPER_INTERFACE_MODE_RGMII
;
248 * Return interface mode for CN7XXX.
250 static cvmx_helper_interface_mode_t
__cvmx_get_mode_cn7xxx(int interface
)
252 union cvmx_gmxx_inf_mode mode
;
254 mode
.u64
= cvmx_read_csr(CVMX_GMXX_INF_MODE(interface
));
259 switch (mode
.cn68xx
.mode
) {
261 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
264 return CVMX_HELPER_INTERFACE_MODE_SGMII
;
266 return CVMX_HELPER_INTERFACE_MODE_XAUI
;
268 return CVMX_HELPER_INTERFACE_MODE_SGMII
;
271 return CVMX_HELPER_INTERFACE_MODE_NPI
;
273 return CVMX_HELPER_INTERFACE_MODE_LOOP
;
275 /* TODO: Implement support for AGL (RGMII). */
276 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
278 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
283 * Get the operating mode of an interface. Depending on the Octeon
284 * chip and configuration, this function returns an enumeration
285 * of the type of packet I/O supported by an interface.
287 * @interface: Interface to probe
289 * Returns Mode of the interface. Unknown or unsupported interfaces return
292 cvmx_helper_interface_mode_t
cvmx_helper_interface_get_mode(int interface
)
294 union cvmx_gmxx_inf_mode mode
;
297 interface
>= cvmx_helper_get_number_of_interfaces())
298 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
303 if (OCTEON_IS_MODEL(OCTEON_CN7XXX
))
304 return __cvmx_get_mode_cn7xxx(interface
);
309 if (OCTEON_IS_MODEL(OCTEON_CN6XXX
) || OCTEON_IS_MODEL(OCTEON_CNF71XX
))
310 return __cvmx_get_mode_octeon2(interface
);
313 * Octeon and Octeon Plus models
316 return CVMX_HELPER_INTERFACE_MODE_NPI
;
318 if (interface
== 3) {
319 if (OCTEON_IS_MODEL(OCTEON_CN56XX
)
320 || OCTEON_IS_MODEL(OCTEON_CN52XX
))
321 return CVMX_HELPER_INTERFACE_MODE_LOOP
;
323 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
326 /* Interface 1 is always disabled on CN31XX and CN30XX */
328 && (OCTEON_IS_MODEL(OCTEON_CN31XX
) || OCTEON_IS_MODEL(OCTEON_CN30XX
)
329 || OCTEON_IS_MODEL(OCTEON_CN50XX
)
330 || OCTEON_IS_MODEL(OCTEON_CN52XX
)))
331 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
333 mode
.u64
= cvmx_read_csr(CVMX_GMXX_INF_MODE(interface
));
335 if (OCTEON_IS_MODEL(OCTEON_CN56XX
) || OCTEON_IS_MODEL(OCTEON_CN52XX
)) {
336 switch (mode
.cn52xx
.mode
) {
338 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
340 return CVMX_HELPER_INTERFACE_MODE_XAUI
;
342 return CVMX_HELPER_INTERFACE_MODE_SGMII
;
344 return CVMX_HELPER_INTERFACE_MODE_PICMG
;
346 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
350 return CVMX_HELPER_INTERFACE_MODE_DISABLED
;
353 if (OCTEON_IS_MODEL(OCTEON_CN38XX
)
354 || OCTEON_IS_MODEL(OCTEON_CN58XX
))
355 return CVMX_HELPER_INTERFACE_MODE_SPI
;
357 return CVMX_HELPER_INTERFACE_MODE_GMII
;
359 return CVMX_HELPER_INTERFACE_MODE_RGMII
;
362 EXPORT_SYMBOL_GPL(cvmx_helper_interface_get_mode
);
365 * Configure the IPD/PIP tagging and QoS options for a specific
366 * port. This function determines the POW work queue entry
367 * contents for a port. The setup performed here is controlled by
368 * the defines in executive-config.h.
370 * @ipd_port: Port to configure. This follows the IPD numbering, not the
371 * per interface numbering
373 * Returns Zero on success, negative on failure
375 static int __cvmx_helper_port_setup_ipd(int ipd_port
)
377 union cvmx_pip_prt_cfgx port_config
;
378 union cvmx_pip_prt_tagx tag_config
;
380 port_config
.u64
= cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port
));
381 tag_config
.u64
= cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port
));
383 /* Have each port go to a different POW queue */
384 port_config
.s
.qos
= ipd_port
& 0x7;
386 /* Process the headers and place the IP header in the work queue */
387 port_config
.s
.mode
= CVMX_HELPER_INPUT_PORT_SKIP_MODE
;
389 tag_config
.s
.ip6_src_flag
= CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP
;
390 tag_config
.s
.ip6_dst_flag
= CVMX_HELPER_INPUT_TAG_IPV6_DST_IP
;
391 tag_config
.s
.ip6_sprt_flag
= CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT
;
392 tag_config
.s
.ip6_dprt_flag
= CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT
;
393 tag_config
.s
.ip6_nxth_flag
= CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER
;
394 tag_config
.s
.ip4_src_flag
= CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP
;
395 tag_config
.s
.ip4_dst_flag
= CVMX_HELPER_INPUT_TAG_IPV4_DST_IP
;
396 tag_config
.s
.ip4_sprt_flag
= CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT
;
397 tag_config
.s
.ip4_dprt_flag
= CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT
;
398 tag_config
.s
.ip4_pctl_flag
= CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL
;
399 tag_config
.s
.inc_prt_flag
= CVMX_HELPER_INPUT_TAG_INPUT_PORT
;
400 tag_config
.s
.tcp6_tag_type
= CVMX_HELPER_INPUT_TAG_TYPE
;
401 tag_config
.s
.tcp4_tag_type
= CVMX_HELPER_INPUT_TAG_TYPE
;
402 tag_config
.s
.ip6_tag_type
= CVMX_HELPER_INPUT_TAG_TYPE
;
403 tag_config
.s
.ip4_tag_type
= CVMX_HELPER_INPUT_TAG_TYPE
;
404 tag_config
.s
.non_tag_type
= CVMX_HELPER_INPUT_TAG_TYPE
;
405 /* Put all packets in group 0. Other groups can be used by the app */
406 tag_config
.s
.grp
= 0;
408 cvmx_pip_config_port(ipd_port
, port_config
, tag_config
);
414 * This function sets the interface_port_count[interface] correctly,
415 * without modifying any hardware configuration. Hardware setup of
416 * the ports will be performed later.
418 * @interface: Interface to probe
420 * Returns Zero on success, negative on failure
422 int cvmx_helper_interface_enumerate(int interface
)
424 switch (cvmx_helper_interface_get_mode(interface
)) {
425 /* These types don't support ports to IPD/PKO */
426 case CVMX_HELPER_INTERFACE_MODE_DISABLED
:
427 case CVMX_HELPER_INTERFACE_MODE_PCIE
:
428 interface_port_count
[interface
] = 0;
430 /* XAUI is a single high speed port */
431 case CVMX_HELPER_INTERFACE_MODE_XAUI
:
432 interface_port_count
[interface
] =
433 __cvmx_helper_xaui_enumerate(interface
);
436 * RGMII/GMII/MII are all treated about the same. Most
437 * functions refer to these ports as RGMII.
439 case CVMX_HELPER_INTERFACE_MODE_RGMII
:
440 case CVMX_HELPER_INTERFACE_MODE_GMII
:
441 interface_port_count
[interface
] =
442 __cvmx_helper_rgmii_enumerate(interface
);
445 * SPI4 can have 1-16 ports depending on the device at
448 case CVMX_HELPER_INTERFACE_MODE_SPI
:
449 interface_port_count
[interface
] =
450 __cvmx_helper_spi_enumerate(interface
);
453 * SGMII can have 1-4 ports depending on how many are
456 case CVMX_HELPER_INTERFACE_MODE_SGMII
:
457 case CVMX_HELPER_INTERFACE_MODE_PICMG
:
458 interface_port_count
[interface
] =
459 __cvmx_helper_sgmii_enumerate(interface
);
461 /* PCI target Network Packet Interface */
462 case CVMX_HELPER_INTERFACE_MODE_NPI
:
463 interface_port_count
[interface
] =
464 __cvmx_helper_npi_enumerate(interface
);
467 * Special loopback only ports. These are not the same
468 * as other ports in loopback mode.
470 case CVMX_HELPER_INTERFACE_MODE_LOOP
:
471 interface_port_count
[interface
] =
472 __cvmx_helper_loop_enumerate(interface
);
476 interface_port_count
[interface
] =
477 __cvmx_helper_board_interface_probe(interface
,
481 /* Make sure all global variables propagate to other cores */
488 * This function probes an interface to determine the actual
489 * number of hardware ports connected to it. It doesn't setup the
490 * ports or enable them. The main goal here is to set the global
491 * interface_port_count[interface] correctly. Hardware setup of the
492 * ports will be performed later.
494 * @interface: Interface to probe
496 * Returns Zero on success, negative on failure
498 int cvmx_helper_interface_probe(int interface
)
500 cvmx_helper_interface_enumerate(interface
);
501 /* At this stage in the game we don't want packets to be moving yet.
502 The following probe calls should perform hardware setup
503 needed to determine port counts. Receive must still be disabled */
504 switch (cvmx_helper_interface_get_mode(interface
)) {
505 /* These types don't support ports to IPD/PKO */
506 case CVMX_HELPER_INTERFACE_MODE_DISABLED
:
507 case CVMX_HELPER_INTERFACE_MODE_PCIE
:
509 /* XAUI is a single high speed port */
510 case CVMX_HELPER_INTERFACE_MODE_XAUI
:
511 __cvmx_helper_xaui_probe(interface
);
514 * RGMII/GMII/MII are all treated about the same. Most
515 * functions refer to these ports as RGMII.
517 case CVMX_HELPER_INTERFACE_MODE_RGMII
:
518 case CVMX_HELPER_INTERFACE_MODE_GMII
:
519 __cvmx_helper_rgmii_probe(interface
);
522 * SPI4 can have 1-16 ports depending on the device at
525 case CVMX_HELPER_INTERFACE_MODE_SPI
:
526 __cvmx_helper_spi_probe(interface
);
529 * SGMII can have 1-4 ports depending on how many are
532 case CVMX_HELPER_INTERFACE_MODE_SGMII
:
533 case CVMX_HELPER_INTERFACE_MODE_PICMG
:
534 __cvmx_helper_sgmii_probe(interface
);
536 /* PCI target Network Packet Interface */
537 case CVMX_HELPER_INTERFACE_MODE_NPI
:
538 __cvmx_helper_npi_probe(interface
);
541 * Special loopback only ports. These are not the same
542 * as other ports in loopback mode.
544 case CVMX_HELPER_INTERFACE_MODE_LOOP
:
545 __cvmx_helper_loop_probe(interface
);
549 /* Make sure all global variables propagate to other cores */
556 * Setup the IPD/PIP for the ports on an interface. Packet
557 * classification and tagging are set for every port on the
558 * interface. The number of ports on the interface must already
561 * @interface: Interface to setup IPD/PIP for
563 * Returns Zero on success, negative on failure
565 static int __cvmx_helper_interface_setup_ipd(int interface
)
567 int ipd_port
= cvmx_helper_get_ipd_port(interface
, 0);
568 int num_ports
= interface_port_count
[interface
];
570 while (num_ports
--) {
571 __cvmx_helper_port_setup_ipd(ipd_port
);
578 * Setup global setting for IPD/PIP not related to a specific
579 * interface or port. This must be called before IPD is enabled.
581 * Returns Zero on success, negative on failure.
583 static int __cvmx_helper_global_setup_ipd(void)
585 /* Setup the global packet input options */
586 cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE
/ 8,
587 CVMX_HELPER_FIRST_MBUFF_SKIP
/ 8,
588 CVMX_HELPER_NOT_FIRST_MBUFF_SKIP
/ 8,
589 /* The +8 is to account for the next ptr */
590 (CVMX_HELPER_FIRST_MBUFF_SKIP
+ 8) / 128,
591 /* The +8 is to account for the next ptr */
592 (CVMX_HELPER_NOT_FIRST_MBUFF_SKIP
+ 8) / 128,
594 CVMX_IPD_OPC_MODE_STT
,
595 CVMX_HELPER_ENABLE_BACK_PRESSURE
);
600 * Setup the PKO for the ports on an interface. The number of
601 * queues per port and the priority of each PKO output queue
602 * is set here. PKO must be disabled when this function is called.
604 * @interface: Interface to setup PKO for
606 * Returns Zero on success, negative on failure
608 static int __cvmx_helper_interface_setup_pko(int interface
)
611 * Each packet output queue has an associated priority. The
612 * higher the priority, the more often it can send a packet. A
613 * priority of 8 means it can send in all 8 rounds of
614 * contention. We're going to make each queue one less than
615 * the last. The vector of priorities has been extended to
616 * support CN5xxx CPUs, where up to 16 queues can be
617 * associated to a port. To keep backward compatibility we
618 * don't change the initial 8 priorities and replicate them in
619 * the second half. With per-core PKO queues (PKO lockless
620 * operation) all queues have the same priority.
622 uint64_t priorities
[16] =
623 { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 };
626 * Setup the IPD/PIP and PKO for the ports discovered
627 * above. Here packet classification, tagging and output
628 * priorities are set.
630 int ipd_port
= cvmx_helper_get_ipd_port(interface
, 0);
631 int num_ports
= interface_port_count
[interface
];
632 while (num_ports
--) {
633 cvmx_pko_config_port(ipd_port
,
634 cvmx_pko_get_base_queue_per_core(ipd_port
,
636 cvmx_pko_get_num_queues(ipd_port
),
644 * Setup global setting for PKO not related to a specific
645 * interface or port. This must be called before PKO is enabled.
647 * Returns Zero on success, negative on failure.
649 static int __cvmx_helper_global_setup_pko(void)
652 * Disable tagwait FAU timeout. This needs to be done before
653 * anyone might start packet output using tags.
655 union cvmx_iob_fau_timeout fau_to
;
657 fau_to
.s
.tout_val
= 0xfff;
658 fau_to
.s
.tout_enb
= 0;
659 cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT
, fau_to
.u64
);
661 if (OCTEON_IS_MODEL(OCTEON_CN68XX
)) {
662 union cvmx_pko_reg_min_pkt min_pkt
;
665 min_pkt
.s
.size1
= 59;
666 min_pkt
.s
.size2
= 59;
667 min_pkt
.s
.size3
= 59;
668 min_pkt
.s
.size4
= 59;
669 min_pkt
.s
.size5
= 59;
670 min_pkt
.s
.size6
= 59;
671 min_pkt
.s
.size7
= 59;
672 cvmx_write_csr(CVMX_PKO_REG_MIN_PKT
, min_pkt
.u64
);
679 * Setup global backpressure setting.
681 * Returns Zero on success, negative on failure
683 static int __cvmx_helper_global_setup_backpressure(void)
685 #if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE
686 /* Disable backpressure if configured to do so */
687 /* Disable backpressure (pause frame) generation */
688 int num_interfaces
= cvmx_helper_get_number_of_interfaces();
690 for (interface
= 0; interface
< num_interfaces
; interface
++) {
691 switch (cvmx_helper_interface_get_mode(interface
)) {
692 case CVMX_HELPER_INTERFACE_MODE_DISABLED
:
693 case CVMX_HELPER_INTERFACE_MODE_PCIE
:
694 case CVMX_HELPER_INTERFACE_MODE_NPI
:
695 case CVMX_HELPER_INTERFACE_MODE_LOOP
:
696 case CVMX_HELPER_INTERFACE_MODE_XAUI
:
698 case CVMX_HELPER_INTERFACE_MODE_RGMII
:
699 case CVMX_HELPER_INTERFACE_MODE_GMII
:
700 case CVMX_HELPER_INTERFACE_MODE_SPI
:
701 case CVMX_HELPER_INTERFACE_MODE_SGMII
:
702 case CVMX_HELPER_INTERFACE_MODE_PICMG
:
703 cvmx_gmx_set_backpressure_override(interface
, 0xf);
713 * Enable packet input/output from the hardware. This function is
714 * called after all internal setup is complete and IPD is enabled.
715 * After this function completes, packets will be accepted from the
716 * hardware ports. PKO should still be disabled to make sure packets
717 * aren't sent out partially setup hardware.
719 * @interface: Interface to enable
721 * Returns Zero on success, negative on failure
723 static int __cvmx_helper_packet_hardware_enable(int interface
)
726 switch (cvmx_helper_interface_get_mode(interface
)) {
727 /* These types don't support ports to IPD/PKO */
728 case CVMX_HELPER_INTERFACE_MODE_DISABLED
:
729 case CVMX_HELPER_INTERFACE_MODE_PCIE
:
732 /* XAUI is a single high speed port */
733 case CVMX_HELPER_INTERFACE_MODE_XAUI
:
734 result
= __cvmx_helper_xaui_enable(interface
);
737 * RGMII/GMII/MII are all treated about the same. Most
738 * functions refer to these ports as RGMII
740 case CVMX_HELPER_INTERFACE_MODE_RGMII
:
741 case CVMX_HELPER_INTERFACE_MODE_GMII
:
742 result
= __cvmx_helper_rgmii_enable(interface
);
745 * SPI4 can have 1-16 ports depending on the device at
748 case CVMX_HELPER_INTERFACE_MODE_SPI
:
749 result
= __cvmx_helper_spi_enable(interface
);
752 * SGMII can have 1-4 ports depending on how many are
755 case CVMX_HELPER_INTERFACE_MODE_SGMII
:
756 case CVMX_HELPER_INTERFACE_MODE_PICMG
:
757 result
= __cvmx_helper_sgmii_enable(interface
);
759 /* PCI target Network Packet Interface */
760 case CVMX_HELPER_INTERFACE_MODE_NPI
:
761 result
= __cvmx_helper_npi_enable(interface
);
764 * Special loopback only ports. These are not the same
765 * as other ports in loopback mode
767 case CVMX_HELPER_INTERFACE_MODE_LOOP
:
768 result
= __cvmx_helper_loop_enable(interface
);
775 * Function to adjust internal IPD pointer alignments
777 * Returns 0 on success
780 static int __cvmx_helper_errata_fix_ipd_ptr_alignment(void)
782 #define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \
783 (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_FIRST_MBUFF_SKIP)
784 #define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \
785 (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_NOT_FIRST_MBUFF_SKIP)
786 #define FIX_IPD_OUTPORT 0
787 /* Ports 0-15 are interface 0, 16-31 are interface 1 */
788 #define INTERFACE(port) (port >> 4)
789 #define INDEX(port) (port & 0xf)
791 union cvmx_pko_command_word0 pko_command
;
792 union cvmx_buf_ptr g_buffer
, pkt_buffer
;
793 struct cvmx_wqe
*work
;
794 int size
, num_segs
= 0, wqe_pcnt
, pkt_pcnt
;
795 union cvmx_gmxx_prtx_cfg gmx_cfg
;
800 /* Save values for restore at end */
802 cvmx_read_csr(CVMX_GMXX_PRTX_CFG
803 (INDEX(FIX_IPD_OUTPORT
), INTERFACE(FIX_IPD_OUTPORT
)));
805 cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT
)));
807 cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT
)));
808 uint64_t rxx_jabber
=
809 cvmx_read_csr(CVMX_GMXX_RXX_JABBER
810 (INDEX(FIX_IPD_OUTPORT
), INTERFACE(FIX_IPD_OUTPORT
)));
812 cvmx_read_csr(CVMX_GMXX_RXX_FRM_MAX
813 (INDEX(FIX_IPD_OUTPORT
), INTERFACE(FIX_IPD_OUTPORT
)));
815 /* Configure port to gig FDX as required for loopback mode */
816 cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT
);
819 * Disable reception on all ports so if traffic is present it
820 * will not interfere.
822 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT
)), 0);
824 __delay(100000000ull);
826 for (retry_loop_cnt
= 0; retry_loop_cnt
< 10; retry_loop_cnt
++) {
828 wqe_pcnt
= cvmx_read_csr(CVMX_IPD_PTR_COUNT
);
829 pkt_pcnt
= (wqe_pcnt
>> 7) & 0x7f;
832 num_segs
= (2 + pkt_pcnt
- wqe_pcnt
) & 3;
840 FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES
+
841 ((num_segs
- 1) * FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES
) -
842 (FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES
/ 2);
844 cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT
)),
845 1 << INDEX(FIX_IPD_OUTPORT
));
850 cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_WQE_POOL
));
851 if (g_buffer
.s
.addr
== 0) {
852 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
853 "buffer allocation failure.\n");
857 g_buffer
.s
.pool
= CVMX_FPA_WQE_POOL
;
858 g_buffer
.s
.size
= num_segs
;
862 cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL
));
863 if (pkt_buffer
.s
.addr
== 0) {
864 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
865 "buffer allocation failure.\n");
869 pkt_buffer
.s
.pool
= CVMX_FPA_PACKET_POOL
;
870 pkt_buffer
.s
.size
= FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES
;
872 p64
= (uint64_t *) cvmx_phys_to_ptr(pkt_buffer
.s
.addr
);
873 p64
[0] = 0xffffffffffff0000ull
;
874 p64
[1] = 0x08004510ull
;
875 p64
[2] = ((uint64_t) (size
- 14) << 48) | 0x5ae740004000ull
;
876 p64
[3] = 0x3a5fc0a81073c0a8ull
;
878 for (i
= 0; i
< num_segs
; i
++) {
881 FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES
;
883 if (i
== (num_segs
- 1))
886 *(uint64_t *) cvmx_phys_to_ptr(g_buffer
.s
.addr
+
887 8 * i
) = pkt_buffer
.u64
;
890 /* Build the PKO command */
892 pko_command
.s
.segs
= num_segs
;
893 pko_command
.s
.total_bytes
= size
;
894 pko_command
.s
.dontfree
= 0;
895 pko_command
.s
.gather
= 1;
898 cvmx_read_csr(CVMX_GMXX_PRTX_CFG
899 (INDEX(FIX_IPD_OUTPORT
),
900 INTERFACE(FIX_IPD_OUTPORT
)));
902 cvmx_write_csr(CVMX_GMXX_PRTX_CFG
903 (INDEX(FIX_IPD_OUTPORT
),
904 INTERFACE(FIX_IPD_OUTPORT
)), gmx_cfg
.u64
);
905 cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT
)),
906 1 << INDEX(FIX_IPD_OUTPORT
));
907 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT
)),
908 1 << INDEX(FIX_IPD_OUTPORT
));
910 cvmx_write_csr(CVMX_GMXX_RXX_JABBER
911 (INDEX(FIX_IPD_OUTPORT
),
912 INTERFACE(FIX_IPD_OUTPORT
)), 65392 - 14 - 4);
913 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
914 (INDEX(FIX_IPD_OUTPORT
),
915 INTERFACE(FIX_IPD_OUTPORT
)), 65392 - 14 - 4);
917 cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT
,
918 cvmx_pko_get_base_queue
920 CVMX_PKO_LOCK_CMD_QUEUE
);
921 cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT
,
922 cvmx_pko_get_base_queue
923 (FIX_IPD_OUTPORT
), pko_command
,
924 g_buffer
, CVMX_PKO_LOCK_CMD_QUEUE
);
929 work
= cvmx_pow_work_request_sync(CVMX_POW_WAIT
);
931 } while ((work
== NULL
) && (retry_cnt
> 0));
934 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
935 "get_work() timeout occurred.\n");
939 cvmx_helper_free_packet_data(work
);
944 /* Return CSR configs to saved values */
945 cvmx_write_csr(CVMX_GMXX_PRTX_CFG
946 (INDEX(FIX_IPD_OUTPORT
), INTERFACE(FIX_IPD_OUTPORT
)),
948 cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT
)),
950 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT
)),
952 cvmx_write_csr(CVMX_GMXX_RXX_JABBER
953 (INDEX(FIX_IPD_OUTPORT
), INTERFACE(FIX_IPD_OUTPORT
)),
955 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
956 (INDEX(FIX_IPD_OUTPORT
), INTERFACE(FIX_IPD_OUTPORT
)),
958 cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT
)), 0);
962 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n");
969 * Called after all internal packet IO paths are setup. This
970 * function enables IPD/PIP and begins packet input and output.
972 * Returns Zero on success, negative on failure
974 int cvmx_helper_ipd_and_packet_input_enable(void)
983 * Time to enable hardware ports packet input and output. Note
984 * that at this point IPD/PIP must be fully functional and PKO
987 num_interfaces
= cvmx_helper_get_number_of_interfaces();
988 for (interface
= 0; interface
< num_interfaces
; interface
++) {
989 if (cvmx_helper_ports_on_interface(interface
) > 0)
990 __cvmx_helper_packet_hardware_enable(interface
);
993 /* Finally enable PKO now that the entire path is up and running */
996 if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1
)
997 || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1
))
998 && (cvmx_sysinfo_get()->board_type
!= CVMX_BOARD_TYPE_SIM
))
999 __cvmx_helper_errata_fix_ipd_ptr_alignment();
1002 EXPORT_SYMBOL_GPL(cvmx_helper_ipd_and_packet_input_enable
);
1005 * Initialize the PIP, IPD, and PKO hardware to support
1006 * simple priority based queues for the ethernet ports. Each
1007 * port is configured with a number of priority queues based
1008 * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
1009 * priority than the previous.
1011 * Returns Zero on success, non-zero on failure
1013 int cvmx_helper_initialize_packet_io_global(void)
1017 union cvmx_l2c_cfg l2c_cfg
;
1018 const int num_interfaces
= cvmx_helper_get_number_of_interfaces();
1021 * CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to
1024 if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0
))
1025 __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
1028 * Tell L2 to give the IOB statically higher priority compared
1029 * to the cores. This avoids conditions where IO blocks might
1030 * be starved under very high L2 loads.
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
);
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",
1043 cvmx_helper_ports_on_interface(interface
),
1044 cvmx_helper_interface_mode_to_string
1045 (cvmx_helper_interface_get_mode
1047 result
|= __cvmx_helper_interface_setup_ipd(interface
);
1048 result
|= __cvmx_helper_interface_setup_pko(interface
);
1051 result
|= __cvmx_helper_global_setup_ipd();
1052 result
|= __cvmx_helper_global_setup_pko();
1054 /* Enable any flow control and backpressure */
1055 result
|= __cvmx_helper_global_setup_backpressure();
1057 #if CVMX_HELPER_ENABLE_IPD
1058 result
|= cvmx_helper_ipd_and_packet_input_enable();
1062 EXPORT_SYMBOL_GPL(cvmx_helper_initialize_packet_io_global
);
1065 * Return the link state of an IPD/PKO port as returned by
1066 * auto negotiation. The result of this function may not match
1067 * Octeon's link config if auto negotiation has changed since
1068 * the last call to cvmx_helper_link_set().
1070 * @ipd_port: IPD/PKO port to query
1072 * Returns Link state
1074 union cvmx_helper_link_info
cvmx_helper_link_get(int ipd_port
)
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
);
1080 /* The default result will be a down link unless the code below
1084 if (index
>= cvmx_helper_ports_on_interface(interface
))
1087 switch (cvmx_helper_interface_get_mode(interface
)) {
1088 case CVMX_HELPER_INTERFACE_MODE_DISABLED
:
1089 case CVMX_HELPER_INTERFACE_MODE_PCIE
:
1090 /* Network links are not supported */
1092 case CVMX_HELPER_INTERFACE_MODE_XAUI
:
1093 result
= __cvmx_helper_xaui_link_get(ipd_port
);
1095 case CVMX_HELPER_INTERFACE_MODE_GMII
:
1097 result
= __cvmx_helper_rgmii_link_get(ipd_port
);
1099 WARN_ONCE(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;
1105 case CVMX_HELPER_INTERFACE_MODE_RGMII
:
1106 result
= __cvmx_helper_rgmii_link_get(ipd_port
);
1108 case CVMX_HELPER_INTERFACE_MODE_SPI
:
1109 result
= __cvmx_helper_spi_link_get(ipd_port
);
1111 case CVMX_HELPER_INTERFACE_MODE_SGMII
:
1112 case CVMX_HELPER_INTERFACE_MODE_PICMG
:
1113 result
= __cvmx_helper_sgmii_link_get(ipd_port
);
1115 case CVMX_HELPER_INTERFACE_MODE_NPI
:
1116 case CVMX_HELPER_INTERFACE_MODE_LOOP
:
1117 /* Network links are not supported */
1122 EXPORT_SYMBOL_GPL(cvmx_helper_link_get
);
1125 * Configure an IPD/PKO port for the specified link state. This
1126 * function does not influence auto negotiation at the PHY level.
1127 * The passed link state must always match the link state returned
1128 * by cvmx_helper_link_get().
1130 * @ipd_port: IPD/PKO port to configure
1131 * @link_info: The new link state
1133 * Returns Zero on success, negative on failure
1135 int cvmx_helper_link_set(int ipd_port
, union cvmx_helper_link_info link_info
)
1138 int interface
= cvmx_helper_get_interface_num(ipd_port
);
1139 int index
= cvmx_helper_get_interface_index_num(ipd_port
);
1141 if (index
>= cvmx_helper_ports_on_interface(interface
))
1144 switch (cvmx_helper_interface_get_mode(interface
)) {
1145 case CVMX_HELPER_INTERFACE_MODE_DISABLED
:
1146 case CVMX_HELPER_INTERFACE_MODE_PCIE
:
1148 case CVMX_HELPER_INTERFACE_MODE_XAUI
:
1149 result
= __cvmx_helper_xaui_link_set(ipd_port
, link_info
);
1152 * RGMII/GMII/MII are all treated about the same. Most
1153 * functions refer to these ports as RGMII.
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
);
1159 case CVMX_HELPER_INTERFACE_MODE_SPI
:
1160 result
= __cvmx_helper_spi_link_set(ipd_port
, link_info
);
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
);
1166 case CVMX_HELPER_INTERFACE_MODE_NPI
:
1167 case CVMX_HELPER_INTERFACE_MODE_LOOP
:
1172 EXPORT_SYMBOL_GPL(cvmx_helper_link_set
);