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:
108 case CVMX_BOARD_TYPE_CUST_LANNER_MR730:
115 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
123 * Return the number of ports on an interface. Depending on the
124 * chip and configuration, this can be 1-16. A value of 0
125 * specifies that the interface doesn't exist or isn't usable.
127 * @param interface Interface to get the port count for
129 * @return Number of ports on interface. Can be Zero.
131 int cvmx_helper_ports_on_interface(int interface)
133 return interface_port_count[interface];
138 * Get the operating mode of an interface. Depending on the Octeon
139 * chip and configuration, this function returns an enumeration
140 * of the type of packet I/O supported by an interface.
142 * @param interface Interface to probe
144 * @return Mode of the interface. Unknown or unsupported interfaces return
147 cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
149 cvmx_gmxx_inf_mode_t mode;
151 return CVMX_HELPER_INTERFACE_MODE_NPI;
155 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
156 return CVMX_HELPER_INTERFACE_MODE_LOOP;
158 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
161 if (interface == 0 && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5 && cvmx_sysinfo_get()->board_rev_major == 1)
163 /* Lie about interface type of CN3005 board. This board has a switch on port 1 like
164 ** the other evaluation boards, but it is connected over RGMII instead of GMII. Report
165 ** GMII mode so that the speed is forced to 1 Gbit full duplex. Other than some initial configuration
166 ** (which does not use the output of this function) there is no difference in setup between GMII and RGMII modes.
168 return CVMX_HELPER_INTERFACE_MODE_GMII;
171 /* Interface 1 is always disabled on CN31XX and CN30XX */
172 if ((interface == 1) && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN50XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)))
173 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
175 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
177 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
179 switch(mode.cn56xx.mode)
181 case 0: return CVMX_HELPER_INTERFACE_MODE_DISABLED;
182 case 1: return CVMX_HELPER_INTERFACE_MODE_XAUI;
183 case 2: return CVMX_HELPER_INTERFACE_MODE_SGMII;
184 case 3: return CVMX_HELPER_INTERFACE_MODE_PICMG;
185 default:return CVMX_HELPER_INTERFACE_MODE_DISABLED;
191 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
195 if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
196 return CVMX_HELPER_INTERFACE_MODE_SPI;
198 return CVMX_HELPER_INTERFACE_MODE_GMII;
201 return CVMX_HELPER_INTERFACE_MODE_RGMII;
208 * Configure the IPD/PIP tagging and QoS options for a specific
209 * port. This function determines the POW work queue entry
210 * contents for a port. The setup performed here is controlled by
211 * the defines in executive-config.h.
213 * @param ipd_port Port to configure. This follows the IPD numbering, not the
214 * per interface numbering
216 * @return Zero on success, negative on failure
218 static int __cvmx_helper_port_setup_ipd(int ipd_port)
220 cvmx_pip_port_cfg_t port_config;
221 cvmx_pip_port_tag_cfg_t tag_config;
223 port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
224 tag_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port));
226 /* Have each port go to a different POW queue */
227 port_config.s.qos = ipd_port & 0x7;
229 /* Process the headers and place the IP header in the work queue */
230 port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE;
232 tag_config.s.ip6_src_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP;
233 tag_config.s.ip6_dst_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_IP;
234 tag_config.s.ip6_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT;
235 tag_config.s.ip6_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT;
236 tag_config.s.ip6_nxth_flag = CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER;
237 tag_config.s.ip4_src_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP;
238 tag_config.s.ip4_dst_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_IP;
239 tag_config.s.ip4_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT;
240 tag_config.s.ip4_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT;
241 tag_config.s.ip4_pctl_flag = CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL;
242 tag_config.s.inc_prt_flag = CVMX_HELPER_INPUT_TAG_INPUT_PORT;
243 tag_config.s.tcp6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
244 tag_config.s.tcp4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
245 tag_config.s.ip6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
246 tag_config.s.ip4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
247 tag_config.s.non_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
248 /* Put all packets in group 0. Other groups can be used by the app */
249 tag_config.s.grp = 0;
251 cvmx_pip_config_port(ipd_port, port_config, tag_config);
253 /* Give the user a chance to override our setting for each port */
254 if (cvmx_override_ipd_port_setup)
255 cvmx_override_ipd_port_setup(ipd_port);
262 * This function probes an interface to determine the actual
263 * number of hardware ports connected to it. It doesn't setup the
264 * ports or enable them. The main goal here is to set the global
265 * interface_port_count[interface] correctly. Hardware setup of the
266 * ports will be performed later.
268 * @param interface Interface to probe
270 * @return Zero on success, negative on failure
272 int cvmx_helper_interface_probe(int interface)
274 /* At this stage in the game we don't want packets to be moving yet.
275 The following probe calls should perform hardware setup
276 needed to determine port counts. Receive must still be disabled */
277 switch (cvmx_helper_interface_get_mode(interface))
279 /* These types don't support ports to IPD/PKO */
280 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
281 case CVMX_HELPER_INTERFACE_MODE_PCIE:
282 interface_port_count[interface] = 0;
284 /* XAUI is a single high speed port */
285 case CVMX_HELPER_INTERFACE_MODE_XAUI:
286 interface_port_count[interface] = __cvmx_helper_xaui_probe(interface);
288 /* RGMII/GMII/MII are all treated about the same. Most functions
289 refer to these ports as RGMII */
290 case CVMX_HELPER_INTERFACE_MODE_RGMII:
291 case CVMX_HELPER_INTERFACE_MODE_GMII:
292 interface_port_count[interface] = __cvmx_helper_rgmii_probe(interface);
294 /* SPI4 can have 1-16 ports depending on the device at the other end */
295 case CVMX_HELPER_INTERFACE_MODE_SPI:
296 interface_port_count[interface] = __cvmx_helper_spi_probe(interface);
298 /* SGMII can have 1-4 ports depending on how many are hooked up */
299 case CVMX_HELPER_INTERFACE_MODE_SGMII:
300 case CVMX_HELPER_INTERFACE_MODE_PICMG:
301 interface_port_count[interface] = __cvmx_helper_sgmii_probe(interface);
303 /* PCI target Network Packet Interface */
304 case CVMX_HELPER_INTERFACE_MODE_NPI:
305 interface_port_count[interface] = __cvmx_helper_npi_probe(interface);
307 /* Special loopback only ports. These are not the same as other ports
309 case CVMX_HELPER_INTERFACE_MODE_LOOP:
310 interface_port_count[interface] = __cvmx_helper_loop_probe(interface);
314 interface_port_count[interface] = __cvmx_helper_board_interface_probe(interface, interface_port_count[interface]);
316 /* Make sure all global variables propagate to other cores */
325 * Setup the IPD/PIP for the ports on an interface. Packet
326 * classification and tagging are set for every port on the
327 * interface. The number of ports on the interface must already
330 * @param interface Interface to setup IPD/PIP for
332 * @return Zero on success, negative on failure
334 static int __cvmx_helper_interface_setup_ipd(int interface)
336 int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
337 int num_ports = interface_port_count[interface];
341 __cvmx_helper_port_setup_ipd(ipd_port);
350 * Setup global setting for IPD/PIP not related to a specific
351 * interface or port. This must be called before IPD is enabled.
353 * @return Zero on success, negative on failure.
355 static int __cvmx_helper_global_setup_ipd(void)
357 /* Setup the global packet input options */
358 cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE/8,
359 CVMX_HELPER_FIRST_MBUFF_SKIP/8,
360 CVMX_HELPER_NOT_FIRST_MBUFF_SKIP/8,
361 (CVMX_HELPER_FIRST_MBUFF_SKIP+8) / 128, /* The +8 is to account for the next ptr */
362 (CVMX_HELPER_NOT_FIRST_MBUFF_SKIP+8) / 128, /* The +8 is to account for the next ptr */
364 CVMX_IPD_OPC_MODE_STT,
365 CVMX_HELPER_ENABLE_BACK_PRESSURE);
372 * Setup the PKO for the ports on an interface. The number of
373 * queues per port and the priority of each PKO output queue
374 * is set here. PKO must be disabled when this function is called.
376 * @param interface Interface to setup PKO for
378 * @return Zero on success, negative on failure
380 static int __cvmx_helper_interface_setup_pko(int interface)
382 /* Each packet output queue has an associated priority. The higher the
383 priority, the more often it can send a packet. A priority of 8 means
384 it can send in all 8 rounds of contention. We're going to make each
385 queue one less than the last.
386 The vector of priorities has been extended to support CN5xxx CPUs,
387 where up to 16 queues can be associated to a port.
388 To keep backward compatibility we don't change the initial 8
389 priorities and replicate them in the second half.
390 With per-core PKO queues (PKO lockless operation) all queues have
391 the same priority. */
392 uint64_t priorities[16] = {8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1};
394 /* Setup the IPD/PIP and PKO for the ports discovered above. Here packet
395 classification, tagging and output priorities are set */
396 int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
397 int num_ports = interface_port_count[interface];
400 /* Give the user a chance to override the per queue priorities */
401 if (cvmx_override_pko_queue_priority)
402 cvmx_override_pko_queue_priority(ipd_port, priorities);
404 cvmx_pko_config_port(ipd_port, cvmx_pko_get_base_queue_per_core(ipd_port, 0),
405 cvmx_pko_get_num_queues(ipd_port), priorities);
414 * Setup global setting for PKO not related to a specific
415 * interface or port. This must be called before PKO is enabled.
417 * @return Zero on success, negative on failure.
419 static int __cvmx_helper_global_setup_pko(void)
421 /* Disable tagwait FAU timeout. This needs to be done before anyone might
422 start packet output using tags */
423 cvmx_iob_fau_timeout_t fau_to;
425 fau_to.s.tout_val = 0xfff;
426 fau_to.s.tout_enb = 0;
427 cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64);
434 * Setup global backpressure setting.
436 * @return Zero on success, negative on failure
438 static int __cvmx_helper_global_setup_backpressure(void)
440 #if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE
441 /* Disable backpressure if configured to do so */
442 /* Disable backpressure (pause frame) generation */
443 int num_interfaces = cvmx_helper_get_number_of_interfaces();
445 for (interface=0; interface<num_interfaces; interface++)
447 switch (cvmx_helper_interface_get_mode(interface))
449 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
450 case CVMX_HELPER_INTERFACE_MODE_PCIE:
451 case CVMX_HELPER_INTERFACE_MODE_NPI:
452 case CVMX_HELPER_INTERFACE_MODE_LOOP:
453 case CVMX_HELPER_INTERFACE_MODE_XAUI:
455 case CVMX_HELPER_INTERFACE_MODE_RGMII:
456 case CVMX_HELPER_INTERFACE_MODE_GMII:
457 case CVMX_HELPER_INTERFACE_MODE_SPI:
458 case CVMX_HELPER_INTERFACE_MODE_SGMII:
459 case CVMX_HELPER_INTERFACE_MODE_PICMG:
460 cvmx_gmx_set_backpressure_override(interface, 0xf);
464 //cvmx_dprintf("Disabling backpressure\n");
473 * Enable packet input/output from the hardware. This function is
474 * called after all internal setup is complete and IPD is enabled.
475 * After this function completes, packets will be accepted from the
476 * hardware ports. PKO should still be disabled to make sure packets
477 * aren't sent out partially setup hardware.
479 * @param interface Interface to enable
481 * @return Zero on success, negative on failure
483 static int __cvmx_helper_packet_hardware_enable(int interface)
486 switch (cvmx_helper_interface_get_mode(interface))
488 /* These types don't support ports to IPD/PKO */
489 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
490 case CVMX_HELPER_INTERFACE_MODE_PCIE:
493 /* XAUI is a single high speed port */
494 case CVMX_HELPER_INTERFACE_MODE_XAUI:
495 result = __cvmx_helper_xaui_enable(interface);
497 /* RGMII/GMII/MII are all treated about the same. Most functions
498 refer to these ports as RGMII */
499 case CVMX_HELPER_INTERFACE_MODE_RGMII:
500 case CVMX_HELPER_INTERFACE_MODE_GMII:
501 result = __cvmx_helper_rgmii_enable(interface);
503 /* SPI4 can have 1-16 ports depending on the device at the other end */
504 case CVMX_HELPER_INTERFACE_MODE_SPI:
505 result = __cvmx_helper_spi_enable(interface);
507 /* SGMII can have 1-4 ports depending on how many are hooked up */
508 case CVMX_HELPER_INTERFACE_MODE_SGMII:
509 case CVMX_HELPER_INTERFACE_MODE_PICMG:
510 result = __cvmx_helper_sgmii_enable(interface);
512 /* PCI target Network Packet Interface */
513 case CVMX_HELPER_INTERFACE_MODE_NPI:
514 result = __cvmx_helper_npi_enable(interface);
516 /* Special loopback only ports. These are not the same as other ports
518 case CVMX_HELPER_INTERFACE_MODE_LOOP:
519 result = __cvmx_helper_loop_enable(interface);
522 result |= __cvmx_helper_board_hardware_enable(interface);
528 * Called after all internal packet IO paths are setup. This
529 * function enables IPD/PIP and begins packet input and output.
531 * @return Zero on success, negative on failure
533 int cvmx_helper_ipd_and_packet_input_enable(void)
541 /* Time to enable hardware ports packet input and output. Note that at this
542 point IPD/PIP must be fully functional and PKO must be disabled */
543 num_interfaces = cvmx_helper_get_number_of_interfaces();
544 for (interface=0; interface<num_interfaces; interface++)
546 if (cvmx_helper_ports_on_interface(interface) > 0)
548 //cvmx_dprintf("Enabling packet I/O on interface %d\n", interface);
549 __cvmx_helper_packet_hardware_enable(interface);
553 /* Finally enable PKO now that the entire path is up and running */
556 if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1) || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1)) &&
557 (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM))
558 __cvmx_helper_errata_fix_ipd_ptr_alignment();
564 * Initialize the PIP, IPD, and PKO hardware to support
565 * simple priority based queues for the ethernet ports. Each
566 * port is configured with a number of priority queues based
567 * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
568 * priority than the previous.
570 * @return Zero on success, non-zero on failure
572 int cvmx_helper_initialize_packet_io_global(void)
576 cvmx_l2c_cfg_t l2c_cfg;
577 cvmx_smix_en_t smix_en;
578 const int num_interfaces = cvmx_helper_get_number_of_interfaces();
580 /* CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to be disabled */
581 if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
582 __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
584 /* Tell L2 to give the IOB statically higher priority compared to the
585 cores. This avoids conditions where IO blocks might be starved under
586 very high L2 loads */
587 l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
588 l2c_cfg.s.lrf_arb_mode = 0;
589 l2c_cfg.s.rfb_arb_mode = 0;
590 cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
592 /* Make sure SMI/MDIO is enabled so we can query PHYs */
593 smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0));
597 cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64);
600 /* Newer chips actually have two SMI/MDIO interfaces */
601 if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
602 !OCTEON_IS_MODEL(OCTEON_CN58XX) &&
603 !OCTEON_IS_MODEL(OCTEON_CN50XX))
605 smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1));
609 cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64);
613 cvmx_pko_initialize_global();
614 for (interface=0; interface<num_interfaces; interface++)
616 result |= cvmx_helper_interface_probe(interface);
617 if (cvmx_helper_ports_on_interface(interface) > 0)
618 cvmx_dprintf("Interface %d has %d ports (%s)\n",
619 interface, cvmx_helper_ports_on_interface(interface),
620 cvmx_helper_interface_mode_to_string(cvmx_helper_interface_get_mode(interface)));
621 result |= __cvmx_helper_interface_setup_ipd(interface);
622 result |= __cvmx_helper_interface_setup_pko(interface);
625 result |= __cvmx_helper_global_setup_ipd();
626 result |= __cvmx_helper_global_setup_pko();
628 /* Enable any flow control and backpressure */
629 result |= __cvmx_helper_global_setup_backpressure();
631 #if CVMX_HELPER_ENABLE_IPD
632 result |= cvmx_helper_ipd_and_packet_input_enable();
639 * Does core local initialization for packet io
641 * @return Zero on success, non-zero on failure
643 int cvmx_helper_initialize_packet_io_local(void)
645 return cvmx_pko_initialize_local();
650 * Auto configure an IPD/PKO port link state and speed. This
651 * function basically does the equivalent of:
652 * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
654 * @param ipd_port IPD/PKO port to auto configure
656 * @return Link state after configure
658 cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port)
660 cvmx_helper_link_info_t link_info;
661 int interface = cvmx_helper_get_interface_num(ipd_port);
662 int index = cvmx_helper_get_interface_index_num(ipd_port);
664 if (index >= cvmx_helper_ports_on_interface(interface))
670 link_info = cvmx_helper_link_get(ipd_port);
671 if (link_info.u64 == port_link_info[ipd_port].u64)
674 /* If we fail to set the link speed, port_link_info will not change */
675 cvmx_helper_link_set(ipd_port, link_info);
677 /* port_link_info should be the current value, which will be different
678 than expect if cvmx_helper_link_set() failed */
679 return port_link_info[ipd_port];
684 * Return the link state of an IPD/PKO port as returned by
685 * auto negotiation. The result of this function may not match
686 * Octeon's link config if auto negotiation has changed since
687 * the last call to cvmx_helper_link_set().
689 * @param ipd_port IPD/PKO port to query
693 cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
695 cvmx_helper_link_info_t result;
696 int interface = cvmx_helper_get_interface_num(ipd_port);
697 int index = cvmx_helper_get_interface_index_num(ipd_port);
699 /* The default result will be a down link unless the code below
703 if (index >= cvmx_helper_ports_on_interface(interface))
706 switch (cvmx_helper_interface_get_mode(interface))
708 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
709 case CVMX_HELPER_INTERFACE_MODE_PCIE:
710 /* Network links are not supported */
712 case CVMX_HELPER_INTERFACE_MODE_XAUI:
713 result = __cvmx_helper_xaui_link_get(ipd_port);
715 case CVMX_HELPER_INTERFACE_MODE_GMII:
717 result = __cvmx_helper_rgmii_link_get(ipd_port);
720 result.s.full_duplex = 1;
721 result.s.link_up = 1;
722 result.s.speed = 1000;
725 case CVMX_HELPER_INTERFACE_MODE_RGMII:
726 result = __cvmx_helper_rgmii_link_get(ipd_port);
728 case CVMX_HELPER_INTERFACE_MODE_SPI:
729 result = __cvmx_helper_spi_link_get(ipd_port);
731 case CVMX_HELPER_INTERFACE_MODE_SGMII:
732 case CVMX_HELPER_INTERFACE_MODE_PICMG:
733 result = __cvmx_helper_sgmii_link_get(ipd_port);
735 case CVMX_HELPER_INTERFACE_MODE_NPI:
736 case CVMX_HELPER_INTERFACE_MODE_LOOP:
737 /* Network links are not supported */
745 * Configure an IPD/PKO port for the specified link state. This
746 * function does not influence auto negotiation at the PHY level.
747 * The passed link state must always match the link state returned
748 * by cvmx_helper_link_get(). It is normally best to use
749 * cvmx_helper_link_autoconf() instead.
751 * @param ipd_port IPD/PKO port to configure
752 * @param link_info The new link state
754 * @return Zero on success, negative on failure
756 int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
759 int interface = cvmx_helper_get_interface_num(ipd_port);
760 int index = cvmx_helper_get_interface_index_num(ipd_port);
762 if (index >= cvmx_helper_ports_on_interface(interface))
765 switch (cvmx_helper_interface_get_mode(interface))
767 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
768 case CVMX_HELPER_INTERFACE_MODE_PCIE:
770 case CVMX_HELPER_INTERFACE_MODE_XAUI:
771 result = __cvmx_helper_xaui_link_set(ipd_port, link_info);
773 /* RGMII/GMII/MII are all treated about the same. Most functions
774 refer to these ports as RGMII */
775 case CVMX_HELPER_INTERFACE_MODE_RGMII:
776 case CVMX_HELPER_INTERFACE_MODE_GMII:
777 result = __cvmx_helper_rgmii_link_set(ipd_port, link_info);
779 case CVMX_HELPER_INTERFACE_MODE_SPI:
780 result = __cvmx_helper_spi_link_set(ipd_port, link_info);
782 case CVMX_HELPER_INTERFACE_MODE_SGMII:
783 case CVMX_HELPER_INTERFACE_MODE_PICMG:
784 result = __cvmx_helper_sgmii_link_set(ipd_port, link_info);
786 case CVMX_HELPER_INTERFACE_MODE_NPI:
787 case CVMX_HELPER_INTERFACE_MODE_LOOP:
790 /* Set the port_link_info here so that the link status is updated
791 no matter how cvmx_helper_link_set is called. We don't change
792 the value if link_set failed */
794 port_link_info[ipd_port].u64 = link_info.u64;
800 * Configure a port for internal and/or external loopback. Internal loopback
801 * causes packets sent by the port to be received by Octeon. External loopback
802 * causes packets received from the wire to sent out again.
804 * @param ipd_port IPD/PKO port to loopback.
805 * @param enable_internal
806 * Non zero if you want internal loopback
807 * @param enable_external
808 * Non zero if you want external loopback
810 * @return Zero on success, negative on failure.
812 int cvmx_helper_configure_loopback(int ipd_port, int enable_internal, int enable_external)
815 int interface = cvmx_helper_get_interface_num(ipd_port);
816 int index = cvmx_helper_get_interface_index_num(ipd_port);
818 if (index >= cvmx_helper_ports_on_interface(interface))
821 switch (cvmx_helper_interface_get_mode(interface))
823 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
824 case CVMX_HELPER_INTERFACE_MODE_PCIE:
825 case CVMX_HELPER_INTERFACE_MODE_SPI:
826 case CVMX_HELPER_INTERFACE_MODE_NPI:
827 case CVMX_HELPER_INTERFACE_MODE_LOOP:
829 case CVMX_HELPER_INTERFACE_MODE_XAUI:
830 result = __cvmx_helper_xaui_configure_loopback(ipd_port, enable_internal, enable_external);
832 case CVMX_HELPER_INTERFACE_MODE_RGMII:
833 case CVMX_HELPER_INTERFACE_MODE_GMII:
834 result = __cvmx_helper_rgmii_configure_loopback(ipd_port, enable_internal, enable_external);
836 case CVMX_HELPER_INTERFACE_MODE_SGMII:
837 case CVMX_HELPER_INTERFACE_MODE_PICMG:
838 result = __cvmx_helper_sgmii_configure_loopback(ipd_port, enable_internal, enable_external);
844 #endif /* CVMX_ENABLE_PKO_FUNCTIONS */