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 switch (cvmx_sysinfo_get()->board_type) {
105 #if defined(OCTEON_VENDOR_LANNER)
106 case CVMX_BOARD_TYPE_CUST_LANNER_MR955:
113 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
121 * Return the number of ports on an interface. Depending on the
122 * chip and configuration, this can be 1-16. A value of 0
123 * specifies that the interface doesn't exist or isn't usable.
125 * @param interface Interface to get the port count for
127 * @return Number of ports on interface. Can be Zero.
129 int cvmx_helper_ports_on_interface(int interface)
131 return interface_port_count[interface];
136 * Get the operating mode of an interface. Depending on the Octeon
137 * chip and configuration, this function returns an enumeration
138 * of the type of packet I/O supported by an interface.
140 * @param interface Interface to probe
142 * @return Mode of the interface. Unknown or unsupported interfaces return
145 cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
147 cvmx_gmxx_inf_mode_t mode;
149 return CVMX_HELPER_INTERFACE_MODE_NPI;
153 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
154 return CVMX_HELPER_INTERFACE_MODE_LOOP;
156 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
159 if (interface == 0 && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5 && cvmx_sysinfo_get()->board_rev_major == 1)
161 /* Lie about interface type of CN3005 board. This board has a switch on port 1 like
162 ** the other evaluation boards, but it is connected over RGMII instead of GMII. Report
163 ** GMII mode so that the speed is forced to 1 Gbit full duplex. Other than some initial configuration
164 ** (which does not use the output of this function) there is no difference in setup between GMII and RGMII modes.
166 return CVMX_HELPER_INTERFACE_MODE_GMII;
169 /* Interface 1 is always disabled on CN31XX and CN30XX */
170 if ((interface == 1) && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN50XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)))
171 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
173 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
175 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
177 switch(mode.cn56xx.mode)
179 case 0: return CVMX_HELPER_INTERFACE_MODE_DISABLED;
180 case 1: return CVMX_HELPER_INTERFACE_MODE_XAUI;
181 case 2: return CVMX_HELPER_INTERFACE_MODE_SGMII;
182 case 3: return CVMX_HELPER_INTERFACE_MODE_PICMG;
183 default:return CVMX_HELPER_INTERFACE_MODE_DISABLED;
189 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
193 if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
194 return CVMX_HELPER_INTERFACE_MODE_SPI;
196 return CVMX_HELPER_INTERFACE_MODE_GMII;
199 return CVMX_HELPER_INTERFACE_MODE_RGMII;
206 * Configure the IPD/PIP tagging and QoS options for a specific
207 * port. This function determines the POW work queue entry
208 * contents for a port. The setup performed here is controlled by
209 * the defines in executive-config.h.
211 * @param ipd_port Port to configure. This follows the IPD numbering, not the
212 * per interface numbering
214 * @return Zero on success, negative on failure
216 static int __cvmx_helper_port_setup_ipd(int ipd_port)
218 cvmx_pip_port_cfg_t port_config;
219 cvmx_pip_port_tag_cfg_t tag_config;
221 port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
222 tag_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port));
224 /* Have each port go to a different POW queue */
225 port_config.s.qos = ipd_port & 0x7;
227 /* Process the headers and place the IP header in the work queue */
228 port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE;
230 tag_config.s.ip6_src_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP;
231 tag_config.s.ip6_dst_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_IP;
232 tag_config.s.ip6_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT;
233 tag_config.s.ip6_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT;
234 tag_config.s.ip6_nxth_flag = CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER;
235 tag_config.s.ip4_src_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP;
236 tag_config.s.ip4_dst_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_IP;
237 tag_config.s.ip4_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT;
238 tag_config.s.ip4_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT;
239 tag_config.s.ip4_pctl_flag = CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL;
240 tag_config.s.inc_prt_flag = CVMX_HELPER_INPUT_TAG_INPUT_PORT;
241 tag_config.s.tcp6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
242 tag_config.s.tcp4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
243 tag_config.s.ip6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
244 tag_config.s.ip4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
245 tag_config.s.non_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
246 /* Put all packets in group 0. Other groups can be used by the app */
247 tag_config.s.grp = 0;
249 cvmx_pip_config_port(ipd_port, port_config, tag_config);
251 /* Give the user a chance to override our setting for each port */
252 if (cvmx_override_ipd_port_setup)
253 cvmx_override_ipd_port_setup(ipd_port);
260 * This function probes an interface to determine the actual
261 * number of hardware ports connected to it. It doesn't setup the
262 * ports or enable them. The main goal here is to set the global
263 * interface_port_count[interface] correctly. Hardware setup of the
264 * ports will be performed later.
266 * @param interface Interface to probe
268 * @return Zero on success, negative on failure
270 int cvmx_helper_interface_probe(int interface)
272 /* At this stage in the game we don't want packets to be moving yet.
273 The following probe calls should perform hardware setup
274 needed to determine port counts. Receive must still be disabled */
275 switch (cvmx_helper_interface_get_mode(interface))
277 /* These types don't support ports to IPD/PKO */
278 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
279 case CVMX_HELPER_INTERFACE_MODE_PCIE:
280 interface_port_count[interface] = 0;
282 /* XAUI is a single high speed port */
283 case CVMX_HELPER_INTERFACE_MODE_XAUI:
284 interface_port_count[interface] = __cvmx_helper_xaui_probe(interface);
286 /* RGMII/GMII/MII are all treated about the same. Most functions
287 refer to these ports as RGMII */
288 case CVMX_HELPER_INTERFACE_MODE_RGMII:
289 case CVMX_HELPER_INTERFACE_MODE_GMII:
290 interface_port_count[interface] = __cvmx_helper_rgmii_probe(interface);
292 /* SPI4 can have 1-16 ports depending on the device at the other end */
293 case CVMX_HELPER_INTERFACE_MODE_SPI:
294 interface_port_count[interface] = __cvmx_helper_spi_probe(interface);
296 /* SGMII can have 1-4 ports depending on how many are hooked up */
297 case CVMX_HELPER_INTERFACE_MODE_SGMII:
298 case CVMX_HELPER_INTERFACE_MODE_PICMG:
299 interface_port_count[interface] = __cvmx_helper_sgmii_probe(interface);
301 /* PCI target Network Packet Interface */
302 case CVMX_HELPER_INTERFACE_MODE_NPI:
303 interface_port_count[interface] = __cvmx_helper_npi_probe(interface);
305 /* Special loopback only ports. These are not the same as other ports
307 case CVMX_HELPER_INTERFACE_MODE_LOOP:
308 interface_port_count[interface] = __cvmx_helper_loop_probe(interface);
312 interface_port_count[interface] = __cvmx_helper_board_interface_probe(interface, interface_port_count[interface]);
314 /* Make sure all global variables propagate to other cores */
323 * Setup the IPD/PIP for the ports on an interface. Packet
324 * classification and tagging are set for every port on the
325 * interface. The number of ports on the interface must already
328 * @param interface Interface to setup IPD/PIP for
330 * @return Zero on success, negative on failure
332 static int __cvmx_helper_interface_setup_ipd(int interface)
334 int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
335 int num_ports = interface_port_count[interface];
339 __cvmx_helper_port_setup_ipd(ipd_port);
348 * Setup global setting for IPD/PIP not related to a specific
349 * interface or port. This must be called before IPD is enabled.
351 * @return Zero on success, negative on failure.
353 static int __cvmx_helper_global_setup_ipd(void)
355 /* Setup the global packet input options */
356 cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE/8,
357 CVMX_HELPER_FIRST_MBUFF_SKIP/8,
358 CVMX_HELPER_NOT_FIRST_MBUFF_SKIP/8,
359 (CVMX_HELPER_FIRST_MBUFF_SKIP+8) / 128, /* The +8 is to account for the next ptr */
360 (CVMX_HELPER_NOT_FIRST_MBUFF_SKIP+8) / 128, /* The +8 is to account for the next ptr */
362 CVMX_IPD_OPC_MODE_STT,
363 CVMX_HELPER_ENABLE_BACK_PRESSURE);
370 * Setup the PKO for the ports on an interface. The number of
371 * queues per port and the priority of each PKO output queue
372 * is set here. PKO must be disabled when this function is called.
374 * @param interface Interface to setup PKO for
376 * @return Zero on success, negative on failure
378 static int __cvmx_helper_interface_setup_pko(int interface)
380 /* Each packet output queue has an associated priority. The higher the
381 priority, the more often it can send a packet. A priority of 8 means
382 it can send in all 8 rounds of contention. We're going to make each
383 queue one less than the last.
384 The vector of priorities has been extended to support CN5xxx CPUs,
385 where up to 16 queues can be associated to a port.
386 To keep backward compatibility we don't change the initial 8
387 priorities and replicate them in the second half.
388 With per-core PKO queues (PKO lockless operation) all queues have
389 the same priority. */
390 uint64_t priorities[16] = {8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1};
392 /* Setup the IPD/PIP and PKO for the ports discovered above. Here packet
393 classification, tagging and output priorities are set */
394 int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
395 int num_ports = interface_port_count[interface];
398 /* Give the user a chance to override the per queue priorities */
399 if (cvmx_override_pko_queue_priority)
400 cvmx_override_pko_queue_priority(ipd_port, priorities);
402 cvmx_pko_config_port(ipd_port, cvmx_pko_get_base_queue_per_core(ipd_port, 0),
403 cvmx_pko_get_num_queues(ipd_port), priorities);
412 * Setup global setting for PKO not related to a specific
413 * interface or port. This must be called before PKO is enabled.
415 * @return Zero on success, negative on failure.
417 static int __cvmx_helper_global_setup_pko(void)
419 /* Disable tagwait FAU timeout. This needs to be done before anyone might
420 start packet output using tags */
421 cvmx_iob_fau_timeout_t fau_to;
423 fau_to.s.tout_val = 0xfff;
424 fau_to.s.tout_enb = 0;
425 cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64);
432 * Setup global backpressure setting.
434 * @return Zero on success, negative on failure
436 static int __cvmx_helper_global_setup_backpressure(void)
438 #if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE
439 /* Disable backpressure if configured to do so */
440 /* Disable backpressure (pause frame) generation */
441 int num_interfaces = cvmx_helper_get_number_of_interfaces();
443 for (interface=0; interface<num_interfaces; interface++)
445 switch (cvmx_helper_interface_get_mode(interface))
447 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
448 case CVMX_HELPER_INTERFACE_MODE_PCIE:
449 case CVMX_HELPER_INTERFACE_MODE_NPI:
450 case CVMX_HELPER_INTERFACE_MODE_LOOP:
451 case CVMX_HELPER_INTERFACE_MODE_XAUI:
453 case CVMX_HELPER_INTERFACE_MODE_RGMII:
454 case CVMX_HELPER_INTERFACE_MODE_GMII:
455 case CVMX_HELPER_INTERFACE_MODE_SPI:
456 case CVMX_HELPER_INTERFACE_MODE_SGMII:
457 case CVMX_HELPER_INTERFACE_MODE_PICMG:
458 cvmx_gmx_set_backpressure_override(interface, 0xf);
462 //cvmx_dprintf("Disabling backpressure\n");
471 * Enable packet input/output from the hardware. This function is
472 * called after all internal setup is complete and IPD is enabled.
473 * After this function completes, packets will be accepted from the
474 * hardware ports. PKO should still be disabled to make sure packets
475 * aren't sent out partially setup hardware.
477 * @param interface Interface to enable
479 * @return Zero on success, negative on failure
481 static int __cvmx_helper_packet_hardware_enable(int interface)
484 switch (cvmx_helper_interface_get_mode(interface))
486 /* These types don't support ports to IPD/PKO */
487 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
488 case CVMX_HELPER_INTERFACE_MODE_PCIE:
491 /* XAUI is a single high speed port */
492 case CVMX_HELPER_INTERFACE_MODE_XAUI:
493 result = __cvmx_helper_xaui_enable(interface);
495 /* RGMII/GMII/MII are all treated about the same. Most functions
496 refer to these ports as RGMII */
497 case CVMX_HELPER_INTERFACE_MODE_RGMII:
498 case CVMX_HELPER_INTERFACE_MODE_GMII:
499 result = __cvmx_helper_rgmii_enable(interface);
501 /* SPI4 can have 1-16 ports depending on the device at the other end */
502 case CVMX_HELPER_INTERFACE_MODE_SPI:
503 result = __cvmx_helper_spi_enable(interface);
505 /* SGMII can have 1-4 ports depending on how many are hooked up */
506 case CVMX_HELPER_INTERFACE_MODE_SGMII:
507 case CVMX_HELPER_INTERFACE_MODE_PICMG:
508 result = __cvmx_helper_sgmii_enable(interface);
510 /* PCI target Network Packet Interface */
511 case CVMX_HELPER_INTERFACE_MODE_NPI:
512 result = __cvmx_helper_npi_enable(interface);
514 /* Special loopback only ports. These are not the same as other ports
516 case CVMX_HELPER_INTERFACE_MODE_LOOP:
517 result = __cvmx_helper_loop_enable(interface);
520 result |= __cvmx_helper_board_hardware_enable(interface);
526 * Called after all internal packet IO paths are setup. This
527 * function enables IPD/PIP and begins packet input and output.
529 * @return Zero on success, negative on failure
531 int cvmx_helper_ipd_and_packet_input_enable(void)
539 /* Time to enable hardware ports packet input and output. Note that at this
540 point IPD/PIP must be fully functional and PKO must be disabled */
541 num_interfaces = cvmx_helper_get_number_of_interfaces();
542 for (interface=0; interface<num_interfaces; interface++)
544 if (cvmx_helper_ports_on_interface(interface) > 0)
546 //cvmx_dprintf("Enabling packet I/O on interface %d\n", interface);
547 __cvmx_helper_packet_hardware_enable(interface);
551 /* Finally enable PKO now that the entire path is up and running */
554 if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1) || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1)) &&
555 (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM))
556 __cvmx_helper_errata_fix_ipd_ptr_alignment();
562 * Initialize the PIP, IPD, and PKO hardware to support
563 * simple priority based queues for the ethernet ports. Each
564 * port is configured with a number of priority queues based
565 * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
566 * priority than the previous.
568 * @return Zero on success, non-zero on failure
570 int cvmx_helper_initialize_packet_io_global(void)
574 cvmx_l2c_cfg_t l2c_cfg;
575 cvmx_smix_en_t smix_en;
576 const int num_interfaces = cvmx_helper_get_number_of_interfaces();
578 /* CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to be disabled */
579 if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
580 __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
582 /* Tell L2 to give the IOB statically higher priority compared to the
583 cores. This avoids conditions where IO blocks might be starved under
584 very high L2 loads */
585 l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
586 l2c_cfg.s.lrf_arb_mode = 0;
587 l2c_cfg.s.rfb_arb_mode = 0;
588 cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
590 /* Make sure SMI/MDIO is enabled so we can query PHYs */
591 smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0));
595 cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64);
598 /* Newer chips actually have two SMI/MDIO interfaces */
599 if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
600 !OCTEON_IS_MODEL(OCTEON_CN58XX) &&
601 !OCTEON_IS_MODEL(OCTEON_CN50XX))
603 smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1));
607 cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64);
611 cvmx_pko_initialize_global();
612 for (interface=0; interface<num_interfaces; interface++)
614 result |= cvmx_helper_interface_probe(interface);
615 if (cvmx_helper_ports_on_interface(interface) > 0)
616 cvmx_dprintf("Interface %d has %d ports (%s)\n",
617 interface, cvmx_helper_ports_on_interface(interface),
618 cvmx_helper_interface_mode_to_string(cvmx_helper_interface_get_mode(interface)));
619 result |= __cvmx_helper_interface_setup_ipd(interface);
620 result |= __cvmx_helper_interface_setup_pko(interface);
623 result |= __cvmx_helper_global_setup_ipd();
624 result |= __cvmx_helper_global_setup_pko();
626 /* Enable any flow control and backpressure */
627 result |= __cvmx_helper_global_setup_backpressure();
629 #if CVMX_HELPER_ENABLE_IPD
630 result |= cvmx_helper_ipd_and_packet_input_enable();
637 * Does core local initialization for packet io
639 * @return Zero on success, non-zero on failure
641 int cvmx_helper_initialize_packet_io_local(void)
643 return cvmx_pko_initialize_local();
648 * Auto configure an IPD/PKO port link state and speed. This
649 * function basically does the equivalent of:
650 * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
652 * @param ipd_port IPD/PKO port to auto configure
654 * @return Link state after configure
656 cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port)
658 cvmx_helper_link_info_t link_info;
659 int interface = cvmx_helper_get_interface_num(ipd_port);
660 int index = cvmx_helper_get_interface_index_num(ipd_port);
662 if (index >= cvmx_helper_ports_on_interface(interface))
668 link_info = cvmx_helper_link_get(ipd_port);
669 if (link_info.u64 == port_link_info[ipd_port].u64)
672 /* If we fail to set the link speed, port_link_info will not change */
673 cvmx_helper_link_set(ipd_port, link_info);
675 /* port_link_info should be the current value, which will be different
676 than expect if cvmx_helper_link_set() failed */
677 return port_link_info[ipd_port];
682 * Return the link state of an IPD/PKO port as returned by
683 * auto negotiation. The result of this function may not match
684 * Octeon's link config if auto negotiation has changed since
685 * the last call to cvmx_helper_link_set().
687 * @param ipd_port IPD/PKO port to query
691 cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
693 cvmx_helper_link_info_t result;
694 int interface = cvmx_helper_get_interface_num(ipd_port);
695 int index = cvmx_helper_get_interface_index_num(ipd_port);
697 /* The default result will be a down link unless the code below
701 if (index >= cvmx_helper_ports_on_interface(interface))
704 switch (cvmx_helper_interface_get_mode(interface))
706 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
707 case CVMX_HELPER_INTERFACE_MODE_PCIE:
708 /* Network links are not supported */
710 case CVMX_HELPER_INTERFACE_MODE_XAUI:
711 result = __cvmx_helper_xaui_link_get(ipd_port);
713 case CVMX_HELPER_INTERFACE_MODE_GMII:
715 result = __cvmx_helper_rgmii_link_get(ipd_port);
718 result.s.full_duplex = 1;
719 result.s.link_up = 1;
720 result.s.speed = 1000;
723 case CVMX_HELPER_INTERFACE_MODE_RGMII:
724 result = __cvmx_helper_rgmii_link_get(ipd_port);
726 case CVMX_HELPER_INTERFACE_MODE_SPI:
727 result = __cvmx_helper_spi_link_get(ipd_port);
729 case CVMX_HELPER_INTERFACE_MODE_SGMII:
730 case CVMX_HELPER_INTERFACE_MODE_PICMG:
731 result = __cvmx_helper_sgmii_link_get(ipd_port);
733 case CVMX_HELPER_INTERFACE_MODE_NPI:
734 case CVMX_HELPER_INTERFACE_MODE_LOOP:
735 /* Network links are not supported */
743 * Configure an IPD/PKO port for the specified link state. This
744 * function does not influence auto negotiation at the PHY level.
745 * The passed link state must always match the link state returned
746 * by cvmx_helper_link_get(). It is normally best to use
747 * cvmx_helper_link_autoconf() instead.
749 * @param ipd_port IPD/PKO port to configure
750 * @param link_info The new link state
752 * @return Zero on success, negative on failure
754 int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
757 int interface = cvmx_helper_get_interface_num(ipd_port);
758 int index = cvmx_helper_get_interface_index_num(ipd_port);
760 if (index >= cvmx_helper_ports_on_interface(interface))
763 switch (cvmx_helper_interface_get_mode(interface))
765 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
766 case CVMX_HELPER_INTERFACE_MODE_PCIE:
768 case CVMX_HELPER_INTERFACE_MODE_XAUI:
769 result = __cvmx_helper_xaui_link_set(ipd_port, link_info);
771 /* RGMII/GMII/MII are all treated about the same. Most functions
772 refer to these ports as RGMII */
773 case CVMX_HELPER_INTERFACE_MODE_RGMII:
774 case CVMX_HELPER_INTERFACE_MODE_GMII:
775 result = __cvmx_helper_rgmii_link_set(ipd_port, link_info);
777 case CVMX_HELPER_INTERFACE_MODE_SPI:
778 result = __cvmx_helper_spi_link_set(ipd_port, link_info);
780 case CVMX_HELPER_INTERFACE_MODE_SGMII:
781 case CVMX_HELPER_INTERFACE_MODE_PICMG:
782 result = __cvmx_helper_sgmii_link_set(ipd_port, link_info);
784 case CVMX_HELPER_INTERFACE_MODE_NPI:
785 case CVMX_HELPER_INTERFACE_MODE_LOOP:
788 /* Set the port_link_info here so that the link status is updated
789 no matter how cvmx_helper_link_set is called. We don't change
790 the value if link_set failed */
792 port_link_info[ipd_port].u64 = link_info.u64;
798 * Configure a port for internal and/or external loopback. Internal loopback
799 * causes packets sent by the port to be received by Octeon. External loopback
800 * causes packets received from the wire to sent out again.
802 * @param ipd_port IPD/PKO port to loopback.
803 * @param enable_internal
804 * Non zero if you want internal loopback
805 * @param enable_external
806 * Non zero if you want external loopback
808 * @return Zero on success, negative on failure.
810 int cvmx_helper_configure_loopback(int ipd_port, int enable_internal, int enable_external)
813 int interface = cvmx_helper_get_interface_num(ipd_port);
814 int index = cvmx_helper_get_interface_index_num(ipd_port);
816 if (index >= cvmx_helper_ports_on_interface(interface))
819 switch (cvmx_helper_interface_get_mode(interface))
821 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
822 case CVMX_HELPER_INTERFACE_MODE_PCIE:
823 case CVMX_HELPER_INTERFACE_MODE_SPI:
824 case CVMX_HELPER_INTERFACE_MODE_NPI:
825 case CVMX_HELPER_INTERFACE_MODE_LOOP:
827 case CVMX_HELPER_INTERFACE_MODE_XAUI:
828 result = __cvmx_helper_xaui_configure_loopback(ipd_port, enable_internal, enable_external);
830 case CVMX_HELPER_INTERFACE_MODE_RGMII:
831 case CVMX_HELPER_INTERFACE_MODE_GMII:
832 result = __cvmx_helper_rgmii_configure_loopback(ipd_port, enable_internal, enable_external);
834 case CVMX_HELPER_INTERFACE_MODE_SGMII:
835 case CVMX_HELPER_INTERFACE_MODE_PICMG:
836 result = __cvmx_helper_sgmii_configure_loopback(ipd_port, enable_internal, enable_external);
842 #endif /* CVMX_ENABLE_PKO_FUNCTIONS */