1 /***********************license start***************
2 * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * * Neither the name of Cavium Networks nor the names of
19 * its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written
23 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
24 * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
25 * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
26 * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
27 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
28 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
29 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
30 * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
31 * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT
32 * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
35 * For any questions regarding licensing please contact marketing@caviumnetworks.com
37 ***********************license end**************************************/
47 * Helper functions for common, but complicated tasks.
49 * <hr>$Revision: 42150 $<hr>
52 #include "cvmx-bootmem.h"
60 #include "cvmx-sysinfo.h"
61 #include "cvmx-helper.h"
62 #include "cvmx-version.h"
63 #include "cvmx-helper-check-defines.h"
64 #include "cvmx-helper-board.h"
65 #include "cvmx-helper-errata.h"
67 #ifdef CVMX_ENABLE_PKO_FUNCTIONS
70 * cvmx_override_pko_queue_priority(int ipd_port, uint64_t
71 * priorities[16]) is a function pointer. It is meant to allow
72 * customization of the PKO queue priorities based on the port
73 * number. Users should set this pointer to a function before
74 * calling any cvmx-helper operations.
76 CVMX_SHARED void (*cvmx_override_pko_queue_priority)(int pko_port, uint64_t priorities[16]) = NULL;
79 * cvmx_override_ipd_port_setup(int ipd_port) is a function
80 * pointer. It is meant to allow customization of the IPD port
81 * setup before packet input/output comes online. It is called
82 * after cvmx-helper does the default IPD configuration, but
83 * before IPD is enabled. Users should set this pointer to a
84 * function before calling any cvmx-helper operations.
86 CVMX_SHARED void (*cvmx_override_ipd_port_setup)(int ipd_port) = NULL;
88 /* Port count per interface */
89 static CVMX_SHARED int interface_port_count[4] = {0,0,0,0};
90 /* Port last configured link info index by IPD/PKO port */
91 static CVMX_SHARED cvmx_helper_link_info_t port_link_info[CVMX_PIP_NUM_INPUT_PORTS];
95 * Return the number of interfaces the chip has. Each interface
96 * may have multiple ports. Most chips support two interfaces,
97 * but the CNX0XX and CNX1XX are exceptions. These only support
100 * @return Number of interfaces on chip
102 int cvmx_helper_get_number_of_interfaces(void)
104 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
112 * Return the number of ports on an interface. Depending on the
113 * chip and configuration, this can be 1-16. A value of 0
114 * specifies that the interface doesn't exist or isn't usable.
116 * @param interface Interface to get the port count for
118 * @return Number of ports on interface. Can be Zero.
120 int cvmx_helper_ports_on_interface(int interface)
122 return interface_port_count[interface];
127 * Get the operating mode of an interface. Depending on the Octeon
128 * chip and configuration, this function returns an enumeration
129 * of the type of packet I/O supported by an interface.
131 * @param interface Interface to probe
133 * @return Mode of the interface. Unknown or unsupported interfaces return
136 cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
138 cvmx_gmxx_inf_mode_t mode;
140 return CVMX_HELPER_INTERFACE_MODE_NPI;
144 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
145 return CVMX_HELPER_INTERFACE_MODE_LOOP;
147 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
150 if (interface == 0 && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5 && cvmx_sysinfo_get()->board_rev_major == 1)
152 /* Lie about interface type of CN3005 board. This board has a switch on port 1 like
153 ** the other evaluation boards, but it is connected over RGMII instead of GMII. Report
154 ** GMII mode so that the speed is forced to 1 Gbit full duplex. Other than some initial configuration
155 ** (which does not use the output of this function) there is no difference in setup between GMII and RGMII modes.
157 return CVMX_HELPER_INTERFACE_MODE_GMII;
160 /* Interface 1 is always disabled on CN31XX and CN30XX */
161 if ((interface == 1) && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN50XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)))
162 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
164 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
166 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
168 switch(mode.cn56xx.mode)
170 case 0: return CVMX_HELPER_INTERFACE_MODE_DISABLED;
171 case 1: return CVMX_HELPER_INTERFACE_MODE_XAUI;
172 case 2: return CVMX_HELPER_INTERFACE_MODE_SGMII;
173 case 3: return CVMX_HELPER_INTERFACE_MODE_PICMG;
174 default:return CVMX_HELPER_INTERFACE_MODE_DISABLED;
180 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
184 if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
185 return CVMX_HELPER_INTERFACE_MODE_SPI;
187 return CVMX_HELPER_INTERFACE_MODE_GMII;
190 return CVMX_HELPER_INTERFACE_MODE_RGMII;
197 * Configure the IPD/PIP tagging and QoS options for a specific
198 * port. This function determines the POW work queue entry
199 * contents for a port. The setup performed here is controlled by
200 * the defines in executive-config.h.
202 * @param ipd_port Port to configure. This follows the IPD numbering, not the
203 * per interface numbering
205 * @return Zero on success, negative on failure
207 static int __cvmx_helper_port_setup_ipd(int ipd_port)
209 cvmx_pip_port_cfg_t port_config;
210 cvmx_pip_port_tag_cfg_t tag_config;
212 port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
213 tag_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port));
215 /* Have each port go to a different POW queue */
216 port_config.s.qos = ipd_port & 0x7;
218 /* Process the headers and place the IP header in the work queue */
219 port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE;
221 tag_config.s.ip6_src_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP;
222 tag_config.s.ip6_dst_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_IP;
223 tag_config.s.ip6_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT;
224 tag_config.s.ip6_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT;
225 tag_config.s.ip6_nxth_flag = CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER;
226 tag_config.s.ip4_src_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP;
227 tag_config.s.ip4_dst_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_IP;
228 tag_config.s.ip4_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT;
229 tag_config.s.ip4_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT;
230 tag_config.s.ip4_pctl_flag = CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL;
231 tag_config.s.inc_prt_flag = CVMX_HELPER_INPUT_TAG_INPUT_PORT;
232 tag_config.s.tcp6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
233 tag_config.s.tcp4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
234 tag_config.s.ip6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
235 tag_config.s.ip4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
236 tag_config.s.non_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
237 /* Put all packets in group 0. Other groups can be used by the app */
238 tag_config.s.grp = 0;
240 cvmx_pip_config_port(ipd_port, port_config, tag_config);
242 /* Give the user a chance to override our setting for each port */
243 if (cvmx_override_ipd_port_setup)
244 cvmx_override_ipd_port_setup(ipd_port);
251 * This function probes an interface to determine the actual
252 * number of hardware ports connected to it. It doesn't setup the
253 * ports or enable them. The main goal here is to set the global
254 * interface_port_count[interface] correctly. Hardware setup of the
255 * ports will be performed later.
257 * @param interface Interface to probe
259 * @return Zero on success, negative on failure
261 int cvmx_helper_interface_probe(int interface)
263 /* At this stage in the game we don't want packets to be moving yet.
264 The following probe calls should perform hardware setup
265 needed to determine port counts. Receive must still be disabled */
266 switch (cvmx_helper_interface_get_mode(interface))
268 /* These types don't support ports to IPD/PKO */
269 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
270 case CVMX_HELPER_INTERFACE_MODE_PCIE:
271 interface_port_count[interface] = 0;
273 /* XAUI is a single high speed port */
274 case CVMX_HELPER_INTERFACE_MODE_XAUI:
275 interface_port_count[interface] = __cvmx_helper_xaui_probe(interface);
277 /* RGMII/GMII/MII are all treated about the same. Most functions
278 refer to these ports as RGMII */
279 case CVMX_HELPER_INTERFACE_MODE_RGMII:
280 case CVMX_HELPER_INTERFACE_MODE_GMII:
281 interface_port_count[interface] = __cvmx_helper_rgmii_probe(interface);
283 /* SPI4 can have 1-16 ports depending on the device at the other end */
284 case CVMX_HELPER_INTERFACE_MODE_SPI:
285 interface_port_count[interface] = __cvmx_helper_spi_probe(interface);
287 /* SGMII can have 1-4 ports depending on how many are hooked up */
288 case CVMX_HELPER_INTERFACE_MODE_SGMII:
289 case CVMX_HELPER_INTERFACE_MODE_PICMG:
290 interface_port_count[interface] = __cvmx_helper_sgmii_probe(interface);
292 /* PCI target Network Packet Interface */
293 case CVMX_HELPER_INTERFACE_MODE_NPI:
294 interface_port_count[interface] = __cvmx_helper_npi_probe(interface);
296 /* Special loopback only ports. These are not the same as other ports
298 case CVMX_HELPER_INTERFACE_MODE_LOOP:
299 interface_port_count[interface] = __cvmx_helper_loop_probe(interface);
303 interface_port_count[interface] = __cvmx_helper_board_interface_probe(interface, interface_port_count[interface]);
305 /* Make sure all global variables propagate to other cores */
314 * Setup the IPD/PIP for the ports on an interface. Packet
315 * classification and tagging are set for every port on the
316 * interface. The number of ports on the interface must already
319 * @param interface Interface to setup IPD/PIP for
321 * @return Zero on success, negative on failure
323 static int __cvmx_helper_interface_setup_ipd(int interface)
325 int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
326 int num_ports = interface_port_count[interface];
330 __cvmx_helper_port_setup_ipd(ipd_port);
339 * Setup global setting for IPD/PIP not related to a specific
340 * interface or port. This must be called before IPD is enabled.
342 * @return Zero on success, negative on failure.
344 static int __cvmx_helper_global_setup_ipd(void)
346 /* Setup the global packet input options */
347 cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE/8,
348 CVMX_HELPER_FIRST_MBUFF_SKIP/8,
349 CVMX_HELPER_NOT_FIRST_MBUFF_SKIP/8,
350 (CVMX_HELPER_FIRST_MBUFF_SKIP+8) / 128, /* The +8 is to account for the next ptr */
351 (CVMX_HELPER_NOT_FIRST_MBUFF_SKIP+8) / 128, /* The +8 is to account for the next ptr */
353 CVMX_IPD_OPC_MODE_STT,
354 CVMX_HELPER_ENABLE_BACK_PRESSURE);
361 * Setup the PKO for the ports on an interface. The number of
362 * queues per port and the priority of each PKO output queue
363 * is set here. PKO must be disabled when this function is called.
365 * @param interface Interface to setup PKO for
367 * @return Zero on success, negative on failure
369 static int __cvmx_helper_interface_setup_pko(int interface)
371 /* Each packet output queue has an associated priority. The higher the
372 priority, the more often it can send a packet. A priority of 8 means
373 it can send in all 8 rounds of contention. We're going to make each
374 queue one less than the last.
375 The vector of priorities has been extended to support CN5xxx CPUs,
376 where up to 16 queues can be associated to a port.
377 To keep backward compatibility we don't change the initial 8
378 priorities and replicate them in the second half.
379 With per-core PKO queues (PKO lockless operation) all queues have
380 the same priority. */
381 uint64_t priorities[16] = {8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1};
383 /* Setup the IPD/PIP and PKO for the ports discovered above. Here packet
384 classification, tagging and output priorities are set */
385 int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
386 int num_ports = interface_port_count[interface];
389 /* Give the user a chance to override the per queue priorities */
390 if (cvmx_override_pko_queue_priority)
391 cvmx_override_pko_queue_priority(ipd_port, priorities);
393 cvmx_pko_config_port(ipd_port, cvmx_pko_get_base_queue_per_core(ipd_port, 0),
394 cvmx_pko_get_num_queues(ipd_port), priorities);
403 * Setup global setting for PKO not related to a specific
404 * interface or port. This must be called before PKO is enabled.
406 * @return Zero on success, negative on failure.
408 static int __cvmx_helper_global_setup_pko(void)
410 /* Disable tagwait FAU timeout. This needs to be done before anyone might
411 start packet output using tags */
412 cvmx_iob_fau_timeout_t fau_to;
414 fau_to.s.tout_val = 0xfff;
415 fau_to.s.tout_enb = 0;
416 cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64);
423 * Setup global backpressure setting.
425 * @return Zero on success, negative on failure
427 static int __cvmx_helper_global_setup_backpressure(void)
429 #if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE
430 /* Disable backpressure if configured to do so */
431 /* Disable backpressure (pause frame) generation */
432 int num_interfaces = cvmx_helper_get_number_of_interfaces();
434 for (interface=0; interface<num_interfaces; interface++)
436 switch (cvmx_helper_interface_get_mode(interface))
438 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
439 case CVMX_HELPER_INTERFACE_MODE_PCIE:
440 case CVMX_HELPER_INTERFACE_MODE_NPI:
441 case CVMX_HELPER_INTERFACE_MODE_LOOP:
442 case CVMX_HELPER_INTERFACE_MODE_XAUI:
444 case CVMX_HELPER_INTERFACE_MODE_RGMII:
445 case CVMX_HELPER_INTERFACE_MODE_GMII:
446 case CVMX_HELPER_INTERFACE_MODE_SPI:
447 case CVMX_HELPER_INTERFACE_MODE_SGMII:
448 case CVMX_HELPER_INTERFACE_MODE_PICMG:
449 cvmx_gmx_set_backpressure_override(interface, 0xf);
453 //cvmx_dprintf("Disabling backpressure\n");
462 * Enable packet input/output from the hardware. This function is
463 * called after all internal setup is complete and IPD is enabled.
464 * After this function completes, packets will be accepted from the
465 * hardware ports. PKO should still be disabled to make sure packets
466 * aren't sent out partially setup hardware.
468 * @param interface Interface to enable
470 * @return Zero on success, negative on failure
472 static int __cvmx_helper_packet_hardware_enable(int interface)
475 switch (cvmx_helper_interface_get_mode(interface))
477 /* These types don't support ports to IPD/PKO */
478 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
479 case CVMX_HELPER_INTERFACE_MODE_PCIE:
482 /* XAUI is a single high speed port */
483 case CVMX_HELPER_INTERFACE_MODE_XAUI:
484 result = __cvmx_helper_xaui_enable(interface);
486 /* RGMII/GMII/MII are all treated about the same. Most functions
487 refer to these ports as RGMII */
488 case CVMX_HELPER_INTERFACE_MODE_RGMII:
489 case CVMX_HELPER_INTERFACE_MODE_GMII:
490 result = __cvmx_helper_rgmii_enable(interface);
492 /* SPI4 can have 1-16 ports depending on the device at the other end */
493 case CVMX_HELPER_INTERFACE_MODE_SPI:
494 result = __cvmx_helper_spi_enable(interface);
496 /* SGMII can have 1-4 ports depending on how many are hooked up */
497 case CVMX_HELPER_INTERFACE_MODE_SGMII:
498 case CVMX_HELPER_INTERFACE_MODE_PICMG:
499 result = __cvmx_helper_sgmii_enable(interface);
501 /* PCI target Network Packet Interface */
502 case CVMX_HELPER_INTERFACE_MODE_NPI:
503 result = __cvmx_helper_npi_enable(interface);
505 /* Special loopback only ports. These are not the same as other ports
507 case CVMX_HELPER_INTERFACE_MODE_LOOP:
508 result = __cvmx_helper_loop_enable(interface);
511 result |= __cvmx_helper_board_hardware_enable(interface);
517 * Called after all internal packet IO paths are setup. This
518 * function enables IPD/PIP and begins packet input and output.
520 * @return Zero on success, negative on failure
522 int cvmx_helper_ipd_and_packet_input_enable(void)
530 /* Time to enable hardware ports packet input and output. Note that at this
531 point IPD/PIP must be fully functional and PKO must be disabled */
532 num_interfaces = cvmx_helper_get_number_of_interfaces();
533 for (interface=0; interface<num_interfaces; interface++)
535 if (cvmx_helper_ports_on_interface(interface) > 0)
537 //cvmx_dprintf("Enabling packet I/O on interface %d\n", interface);
538 __cvmx_helper_packet_hardware_enable(interface);
542 /* Finally enable PKO now that the entire path is up and running */
545 if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1) || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1)) &&
546 (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM))
547 __cvmx_helper_errata_fix_ipd_ptr_alignment();
553 * Initialize the PIP, IPD, and PKO hardware to support
554 * simple priority based queues for the ethernet ports. Each
555 * port is configured with a number of priority queues based
556 * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
557 * priority than the previous.
559 * @return Zero on success, non-zero on failure
561 int cvmx_helper_initialize_packet_io_global(void)
565 cvmx_l2c_cfg_t l2c_cfg;
566 cvmx_smix_en_t smix_en;
567 const int num_interfaces = cvmx_helper_get_number_of_interfaces();
569 /* CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to be disabled */
570 if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
571 __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
573 /* Tell L2 to give the IOB statically higher priority compared to the
574 cores. This avoids conditions where IO blocks might be starved under
575 very high L2 loads */
576 l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
577 l2c_cfg.s.lrf_arb_mode = 0;
578 l2c_cfg.s.rfb_arb_mode = 0;
579 cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
581 /* Make sure SMI/MDIO is enabled so we can query PHYs */
582 smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0));
586 cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64);
589 /* Newer chips actually have two SMI/MDIO interfaces */
590 if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
591 !OCTEON_IS_MODEL(OCTEON_CN58XX) &&
592 !OCTEON_IS_MODEL(OCTEON_CN50XX))
594 smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1));
598 cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64);
602 cvmx_pko_initialize_global();
603 for (interface=0; interface<num_interfaces; interface++)
605 result |= cvmx_helper_interface_probe(interface);
606 if (cvmx_helper_ports_on_interface(interface) > 0)
607 cvmx_dprintf("Interface %d has %d ports (%s)\n",
608 interface, cvmx_helper_ports_on_interface(interface),
609 cvmx_helper_interface_mode_to_string(cvmx_helper_interface_get_mode(interface)));
610 result |= __cvmx_helper_interface_setup_ipd(interface);
611 result |= __cvmx_helper_interface_setup_pko(interface);
614 result |= __cvmx_helper_global_setup_ipd();
615 result |= __cvmx_helper_global_setup_pko();
617 /* Enable any flow control and backpressure */
618 result |= __cvmx_helper_global_setup_backpressure();
620 #if CVMX_HELPER_ENABLE_IPD
621 result |= cvmx_helper_ipd_and_packet_input_enable();
628 * Does core local initialization for packet io
630 * @return Zero on success, non-zero on failure
632 int cvmx_helper_initialize_packet_io_local(void)
634 return cvmx_pko_initialize_local();
639 * Auto configure an IPD/PKO port link state and speed. This
640 * function basically does the equivalent of:
641 * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
643 * @param ipd_port IPD/PKO port to auto configure
645 * @return Link state after configure
647 cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port)
649 cvmx_helper_link_info_t link_info;
650 int interface = cvmx_helper_get_interface_num(ipd_port);
651 int index = cvmx_helper_get_interface_index_num(ipd_port);
653 if (index >= cvmx_helper_ports_on_interface(interface))
659 link_info = cvmx_helper_link_get(ipd_port);
660 if (link_info.u64 == port_link_info[ipd_port].u64)
663 /* If we fail to set the link speed, port_link_info will not change */
664 cvmx_helper_link_set(ipd_port, link_info);
666 /* port_link_info should be the current value, which will be different
667 than expect if cvmx_helper_link_set() failed */
668 return port_link_info[ipd_port];
673 * Return the link state of an IPD/PKO port as returned by
674 * auto negotiation. The result of this function may not match
675 * Octeon's link config if auto negotiation has changed since
676 * the last call to cvmx_helper_link_set().
678 * @param ipd_port IPD/PKO port to query
682 cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
684 cvmx_helper_link_info_t result;
685 int interface = cvmx_helper_get_interface_num(ipd_port);
686 int index = cvmx_helper_get_interface_index_num(ipd_port);
688 /* The default result will be a down link unless the code below
692 if (index >= cvmx_helper_ports_on_interface(interface))
695 switch (cvmx_helper_interface_get_mode(interface))
697 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
698 case CVMX_HELPER_INTERFACE_MODE_PCIE:
699 /* Network links are not supported */
701 case CVMX_HELPER_INTERFACE_MODE_XAUI:
702 result = __cvmx_helper_xaui_link_get(ipd_port);
704 case CVMX_HELPER_INTERFACE_MODE_GMII:
706 result = __cvmx_helper_rgmii_link_get(ipd_port);
709 result.s.full_duplex = 1;
710 result.s.link_up = 1;
711 result.s.speed = 1000;
714 case CVMX_HELPER_INTERFACE_MODE_RGMII:
715 result = __cvmx_helper_rgmii_link_get(ipd_port);
717 case CVMX_HELPER_INTERFACE_MODE_SPI:
718 result = __cvmx_helper_spi_link_get(ipd_port);
720 case CVMX_HELPER_INTERFACE_MODE_SGMII:
721 case CVMX_HELPER_INTERFACE_MODE_PICMG:
722 result = __cvmx_helper_sgmii_link_get(ipd_port);
724 case CVMX_HELPER_INTERFACE_MODE_NPI:
725 case CVMX_HELPER_INTERFACE_MODE_LOOP:
726 /* Network links are not supported */
734 * Configure an IPD/PKO port for the specified link state. This
735 * function does not influence auto negotiation at the PHY level.
736 * The passed link state must always match the link state returned
737 * by cvmx_helper_link_get(). It is normally best to use
738 * cvmx_helper_link_autoconf() instead.
740 * @param ipd_port IPD/PKO port to configure
741 * @param link_info The new link state
743 * @return Zero on success, negative on failure
745 int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
748 int interface = cvmx_helper_get_interface_num(ipd_port);
749 int index = cvmx_helper_get_interface_index_num(ipd_port);
751 if (index >= cvmx_helper_ports_on_interface(interface))
754 switch (cvmx_helper_interface_get_mode(interface))
756 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
757 case CVMX_HELPER_INTERFACE_MODE_PCIE:
759 case CVMX_HELPER_INTERFACE_MODE_XAUI:
760 result = __cvmx_helper_xaui_link_set(ipd_port, link_info);
762 /* RGMII/GMII/MII are all treated about the same. Most functions
763 refer to these ports as RGMII */
764 case CVMX_HELPER_INTERFACE_MODE_RGMII:
765 case CVMX_HELPER_INTERFACE_MODE_GMII:
766 result = __cvmx_helper_rgmii_link_set(ipd_port, link_info);
768 case CVMX_HELPER_INTERFACE_MODE_SPI:
769 result = __cvmx_helper_spi_link_set(ipd_port, link_info);
771 case CVMX_HELPER_INTERFACE_MODE_SGMII:
772 case CVMX_HELPER_INTERFACE_MODE_PICMG:
773 result = __cvmx_helper_sgmii_link_set(ipd_port, link_info);
775 case CVMX_HELPER_INTERFACE_MODE_NPI:
776 case CVMX_HELPER_INTERFACE_MODE_LOOP:
779 /* Set the port_link_info here so that the link status is updated
780 no matter how cvmx_helper_link_set is called. We don't change
781 the value if link_set failed */
783 port_link_info[ipd_port].u64 = link_info.u64;
789 * Configure a port for internal and/or external loopback. Internal loopback
790 * causes packets sent by the port to be received by Octeon. External loopback
791 * causes packets received from the wire to sent out again.
793 * @param ipd_port IPD/PKO port to loopback.
794 * @param enable_internal
795 * Non zero if you want internal loopback
796 * @param enable_external
797 * Non zero if you want external loopback
799 * @return Zero on success, negative on failure.
801 int cvmx_helper_configure_loopback(int ipd_port, int enable_internal, int enable_external)
804 int interface = cvmx_helper_get_interface_num(ipd_port);
805 int index = cvmx_helper_get_interface_index_num(ipd_port);
807 if (index >= cvmx_helper_ports_on_interface(interface))
810 switch (cvmx_helper_interface_get_mode(interface))
812 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
813 case CVMX_HELPER_INTERFACE_MODE_PCIE:
814 case CVMX_HELPER_INTERFACE_MODE_SPI:
815 case CVMX_HELPER_INTERFACE_MODE_NPI:
816 case CVMX_HELPER_INTERFACE_MODE_LOOP:
818 case CVMX_HELPER_INTERFACE_MODE_XAUI:
819 result = __cvmx_helper_xaui_configure_loopback(ipd_port, enable_internal, enable_external);
821 case CVMX_HELPER_INTERFACE_MODE_RGMII:
822 case CVMX_HELPER_INTERFACE_MODE_GMII:
823 result = __cvmx_helper_rgmii_configure_loopback(ipd_port, enable_internal, enable_external);
825 case CVMX_HELPER_INTERFACE_MODE_SGMII:
826 case CVMX_HELPER_INTERFACE_MODE_PICMG:
827 result = __cvmx_helper_sgmii_configure_loopback(ipd_port, enable_internal, enable_external);
833 #endif /* CVMX_ENABLE_PKO_FUNCTIONS */