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 to abstract board specific data about
48 * network ports from the rest of the cvmx-helper files.
50 * <hr>$Revision: 41946 $<hr>
53 #include "cvmx-app-init.h"
54 #include "cvmx-mdio.h"
55 #include "cvmx-sysinfo.h"
56 #include "cvmx-helper.h"
57 #include "cvmx-helper-util.h"
58 #include "cvmx-helper-board.h"
61 * cvmx_override_board_link_get(int ipd_port) is a function
62 * pointer. It is meant to allow customization of the process of
63 * talking to a PHY to determine link speed. It is called every
64 * time a PHY must be polled for link status. Users should set
65 * this pointer to a function before calling any cvmx-helper
68 CVMX_SHARED cvmx_helper_link_info_t (*cvmx_override_board_link_get)(int ipd_port) = NULL;
71 * Return the MII PHY address associated with the given IPD
72 * port. A result of -1 means there isn't a MII capable PHY
73 * connected to this port. On chips supporting multiple MII
74 * busses the bus number is encoded in bits <15:8>.
76 * This function must be modified for every new Octeon board.
77 * Internally it uses switch statements based on the cvmx_sysinfo
78 * data to determine board types and revisions. It replies on the
79 * fact that every Octeon board receives a unique board type
80 * enumeration from the bootloader.
82 * @param ipd_port Octeon IPD port to get the MII address for.
84 * @return MII PHY address and bus number or -1.
86 int cvmx_helper_board_get_mii_address(int ipd_port)
89 * Board types we have to know at compile-time.
91 #ifdef OCTEON_BOARD_CAPK_0100ND
106 * For board types we can determine at runtime.
108 switch (cvmx_sysinfo_get()->board_type)
110 case CVMX_BOARD_TYPE_SIM:
111 /* Simulator doesn't have MII */
113 case CVMX_BOARD_TYPE_EBT3000:
114 case CVMX_BOARD_TYPE_EBT5800:
115 case CVMX_BOARD_TYPE_THUNDER:
116 case CVMX_BOARD_TYPE_NICPRO2:
117 #if defined(OCTEON_VENDOR_LANNER)
118 case CVMX_BOARD_TYPE_CUST_LANNER_MR955:
120 /* Interface 0 is SPI4, interface 1 is RGMII */
121 if ((ipd_port >= 16) && (ipd_port < 20))
122 return ipd_port - 16;
125 case CVMX_BOARD_TYPE_KODAMA:
126 case CVMX_BOARD_TYPE_EBH3100:
127 case CVMX_BOARD_TYPE_HIKARI:
128 case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
129 case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
130 case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
131 /* Port 0 is WAN connected to a PHY, Port 1 is GMII connected to a
135 else if (ipd_port == 1)
139 case CVMX_BOARD_TYPE_NAC38:
140 /* Board has 8 RGMII ports PHYs are 0-7 */
141 if ((ipd_port >= 0) && (ipd_port < 4))
143 else if ((ipd_port >= 16) && (ipd_port < 20))
144 return ipd_port - 16 + 4;
147 case CVMX_BOARD_TYPE_EBH3000:
148 /* Board has dual SPI4 and no PHYs */
150 case CVMX_BOARD_TYPE_EBH5200:
151 case CVMX_BOARD_TYPE_EBH5201:
152 case CVMX_BOARD_TYPE_EBT5200:
153 /* Board has 4 SGMII ports. The PHYs start right after the MII
154 ports MII0 = 0, MII1 = 1, SGMII = 2-5 */
155 if ((ipd_port >= 0) && (ipd_port < 4))
159 case CVMX_BOARD_TYPE_EBH5600:
160 case CVMX_BOARD_TYPE_EBH5601:
161 /* Board has 8 SGMII ports. 4 connect out, two connect to a switch,
162 and 2 loop to each other */
163 if ((ipd_port >= 0) && (ipd_port < 4))
167 case CVMX_BOARD_TYPE_CUST_NB5:
172 case CVMX_BOARD_TYPE_NIC_XLE_4G:
173 /* Board has 4 SGMII ports. connected QLM3(interface 1) */
174 if ((ipd_port >= 16) && (ipd_port < 20))
175 return ipd_port - 16 + 1;
178 case CVMX_BOARD_TYPE_BBGW_REF:
179 return -1; /* No PHYs are connected to Octeon, everything is through switch */
181 /* Private vendor-defined boards. */
182 #if defined(OCTEON_VENDOR_LANNER)
183 case CVMX_BOARD_TYPE_CUST_LANNER_MR320:
184 /* Port 0 is a Marvell 88E6161 switch, ports 1 and 2 are Marvell
185 88E1111 interfaces. */
199 /* Some unknown board. Somebody forgot to update this function... */
200 cvmx_dprintf("cvmx_helper_board_get_mii_address: Unknown board type %d\n",
201 cvmx_sysinfo_get()->board_type);
208 * This function is the board specific method of determining an
209 * ethernet ports link speed. Most Octeon boards have Marvell PHYs
210 * and are handled by the fall through case. This function must be
211 * updated for boards that don't have the normal Marvell PHYs.
213 * This function must be modified for every new Octeon board.
214 * Internally it uses switch statements based on the cvmx_sysinfo
215 * data to determine board types and revisions. It relies on the
216 * fact that every Octeon board receives a unique board type
217 * enumeration from the bootloader.
219 * @param ipd_port IPD input port associated with the port we want to get link
222 * @return The ports link status. If the link isn't fully resolved, this must
225 cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port)
227 cvmx_helper_link_info_t result;
229 int is_broadcom_phy = 0;
231 /* Give the user a chance to override the processing of this function */
232 if (cvmx_override_board_link_get)
233 return cvmx_override_board_link_get(ipd_port);
235 /* Unless we fix it later, all links are defaulted to down */
238 #if !defined(OCTEON_BOARD_CAPK_0100ND)
239 /* This switch statement should handle all ports that either don't use
240 Marvell PHYS, or don't support in-band status */
241 switch (cvmx_sysinfo_get()->board_type)
243 case CVMX_BOARD_TYPE_SIM:
244 /* The simulator gives you a simulated 1Gbps full duplex link */
245 result.s.link_up = 1;
246 result.s.full_duplex = 1;
247 result.s.speed = 1000;
249 case CVMX_BOARD_TYPE_EBH3100:
250 case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
251 case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
252 case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
253 /* Port 1 on these boards is always Gigabit */
256 result.s.link_up = 1;
257 result.s.full_duplex = 1;
258 result.s.speed = 1000;
261 /* Fall through to the generic code below */
263 case CVMX_BOARD_TYPE_CUST_NB5:
264 /* Port 1 on these boards is always Gigabit */
267 result.s.link_up = 1;
268 result.s.full_duplex = 1;
269 result.s.speed = 1000;
272 else /* The other port uses a broadcom PHY */
275 case CVMX_BOARD_TYPE_BBGW_REF:
276 /* Port 1 on these boards is always Gigabit */
279 /* Port 2 is not hooked up */
285 /* Ports 0 and 1 connect to the switch */
286 result.s.link_up = 1;
287 result.s.full_duplex = 1;
288 result.s.speed = 1000;
292 /* Private vendor-defined boards. */
293 #if defined(OCTEON_VENDOR_LANNER)
294 case CVMX_BOARD_TYPE_CUST_LANNER_MR320:
295 /* Port 0 connects to the switch */
298 result.s.link_up = 1;
299 result.s.full_duplex = 1;
300 result.s.speed = 1000;
308 phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
313 /* Below we are going to read SMI/MDIO register 0x19 which works
315 int phy_status = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, 0x19);
316 switch ((phy_status>>8) & 0x7)
322 result.s.link_up = 1;
323 result.s.full_duplex = 0;
327 result.s.link_up = 1;
328 result.s.full_duplex = 1;
332 result.s.link_up = 1;
333 result.s.full_duplex = 0;
334 result.s.speed = 100;
337 result.s.link_up = 1;
338 result.s.full_duplex = 1;
339 result.s.speed = 100;
342 result.s.link_up = 1;
343 result.s.full_duplex = 1;
344 result.s.speed = 100;
347 result.s.link_up = 1;
348 result.s.full_duplex = 0;
349 result.s.speed = 1000;
352 result.s.link_up = 1;
353 result.s.full_duplex = 1;
354 result.s.speed = 1000;
360 /* This code assumes we are using a Marvell Gigabit PHY. All the
361 speed information can be read from register 17 in one go. Somebody
362 using a different PHY will need to handle it above in the board
364 int phy_status = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, 17);
366 /* If the resolve bit 11 isn't set, see if autoneg is turned off
367 (bit 12, reg 0). The resolve bit doesn't get set properly when
368 autoneg is off, so force it */
369 if ((phy_status & (1<<11)) == 0)
371 int auto_status = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, 0);
372 if ((auto_status & (1<<12)) == 0)
376 /* Only return a link if the PHY has finished auto negotiation
377 and set the resolved bit (bit 11) */
378 if (phy_status & (1<<11))
380 #if defined(OCTEON_BOARD_CAPK_0100ND)
381 result.s.link_up = (phy_status>>10)&1;
383 result.s.link_up = 1;
385 result.s.full_duplex = ((phy_status>>13)&1);
386 switch ((phy_status>>14)&3)
388 case 0: /* 10 Mbps */
391 case 1: /* 100 Mbps */
392 result.s.speed = 100;
395 result.s.speed = 1000;
397 case 3: /* Illegal */
404 else if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
406 /* We don't have a PHY address, so attempt to use in-band status. It is
407 really important that boards not supporting in-band status never get
408 here. Reading broken in-band status tends to do bad things */
409 cvmx_gmxx_rxx_rx_inbnd_t inband_status;
410 int interface = cvmx_helper_get_interface_num(ipd_port);
411 int index = cvmx_helper_get_interface_index_num(ipd_port);
412 inband_status.u64 = cvmx_read_csr(CVMX_GMXX_RXX_RX_INBND(index, interface));
414 result.s.link_up = inband_status.s.status;
415 result.s.full_duplex = inband_status.s.duplex;
416 switch (inband_status.s.speed)
418 case 0: /* 10 Mbps */
421 case 1: /* 100 Mbps */
422 result.s.speed = 100;
425 result.s.speed = 1000;
427 case 3: /* Illegal */
434 /* We don't have a PHY address and we don't have in-band status. There
435 is no way to determine the link speed. Return down assuming this
440 /* If link is down, return all fields as zero. */
441 if (!result.s.link_up)
449 * This function as a board specific method of changing the PHY
450 * speed, duplex, and auto-negotiation. This programs the PHY and
451 * not Octeon. This can be used to force Octeon's links to
454 * @param phy_addr The address of the PHY to program
455 * @param enable_autoneg
456 * Non zero if you want to enable auto-negotiation.
457 * @param link_info Link speed to program. If the speed is zero and auto-negotiation
458 * is enabled, all possible negotiation speeds are advertised.
460 * @return Zero on success, negative on failure
462 int cvmx_helper_board_link_set_phy(int phy_addr, cvmx_helper_board_set_phy_link_flags_types_t link_flags,
463 cvmx_helper_link_info_t link_info)
466 /* Set the flow control settings based on link_flags */
467 if ((link_flags & set_phy_link_flags_flow_control_mask) != set_phy_link_flags_flow_control_dont_touch)
469 cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
470 reg_autoneg_adver.u16 = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
471 reg_autoneg_adver.s.asymmetric_pause = (link_flags & set_phy_link_flags_flow_control_mask) == set_phy_link_flags_flow_control_enable;
472 reg_autoneg_adver.s.pause = (link_flags & set_phy_link_flags_flow_control_mask) == set_phy_link_flags_flow_control_enable;
473 cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_AUTONEG_ADVER, reg_autoneg_adver.u16);
476 /* If speed isn't set and autoneg is on advertise all supported modes */
477 if ((link_flags & set_phy_link_flags_autoneg) && (link_info.s.speed == 0))
479 cvmx_mdio_phy_reg_control_t reg_control;
480 cvmx_mdio_phy_reg_status_t reg_status;
481 cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
482 cvmx_mdio_phy_reg_extended_status_t reg_extended_status;
483 cvmx_mdio_phy_reg_control_1000_t reg_control_1000;
485 reg_status.u16 = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_STATUS);
486 reg_autoneg_adver.u16 = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
487 reg_autoneg_adver.s.advert_100base_t4 = reg_status.s.capable_100base_t4;
488 reg_autoneg_adver.s.advert_10base_tx_full = reg_status.s.capable_10_full;
489 reg_autoneg_adver.s.advert_10base_tx_half = reg_status.s.capable_10_half;
490 reg_autoneg_adver.s.advert_100base_tx_full = reg_status.s.capable_100base_x_full;
491 reg_autoneg_adver.s.advert_100base_tx_half = reg_status.s.capable_100base_x_half;
492 cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_AUTONEG_ADVER, reg_autoneg_adver.u16);
493 if (reg_status.s.capable_extended_status)
495 reg_extended_status.u16 = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_EXTENDED_STATUS);
496 reg_control_1000.u16 = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_CONTROL_1000);
497 reg_control_1000.s.advert_1000base_t_full = reg_extended_status.s.capable_1000base_t_full;
498 reg_control_1000.s.advert_1000base_t_half = reg_extended_status.s.capable_1000base_t_half;
499 cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_CONTROL_1000, reg_control_1000.u16);
501 reg_control.u16 = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_CONTROL);
502 reg_control.s.autoneg_enable = 1;
503 reg_control.s.restart_autoneg = 1;
504 cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
506 else if ((link_flags & set_phy_link_flags_autoneg))
508 cvmx_mdio_phy_reg_control_t reg_control;
509 cvmx_mdio_phy_reg_status_t reg_status;
510 cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
511 cvmx_mdio_phy_reg_extended_status_t reg_extended_status;
512 cvmx_mdio_phy_reg_control_1000_t reg_control_1000;
514 reg_status.u16 = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_STATUS);
515 reg_autoneg_adver.u16 = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
516 reg_autoneg_adver.s.advert_100base_t4 = 0;
517 reg_autoneg_adver.s.advert_10base_tx_full = 0;
518 reg_autoneg_adver.s.advert_10base_tx_half = 0;
519 reg_autoneg_adver.s.advert_100base_tx_full = 0;
520 reg_autoneg_adver.s.advert_100base_tx_half = 0;
521 if (reg_status.s.capable_extended_status)
523 reg_extended_status.u16 = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_EXTENDED_STATUS);
524 reg_control_1000.u16 = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_CONTROL_1000);
525 reg_control_1000.s.advert_1000base_t_full = 0;
526 reg_control_1000.s.advert_1000base_t_half = 0;
528 switch (link_info.s.speed)
531 reg_autoneg_adver.s.advert_10base_tx_full = link_info.s.full_duplex;
532 reg_autoneg_adver.s.advert_10base_tx_half = !link_info.s.full_duplex;
535 reg_autoneg_adver.s.advert_100base_tx_full = link_info.s.full_duplex;
536 reg_autoneg_adver.s.advert_100base_tx_half = !link_info.s.full_duplex;
539 reg_control_1000.s.advert_1000base_t_full = link_info.s.full_duplex;
540 reg_control_1000.s.advert_1000base_t_half = !link_info.s.full_duplex;
543 cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_AUTONEG_ADVER, reg_autoneg_adver.u16);
544 if (reg_status.s.capable_extended_status)
545 cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_CONTROL_1000, reg_control_1000.u16);
546 reg_control.u16 = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_CONTROL);
547 reg_control.s.autoneg_enable = 1;
548 reg_control.s.restart_autoneg = 1;
549 cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
553 cvmx_mdio_phy_reg_control_t reg_control;
554 reg_control.u16 = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_CONTROL);
555 reg_control.s.autoneg_enable = 0;
556 reg_control.s.restart_autoneg = 1;
557 reg_control.s.duplex = link_info.s.full_duplex;
558 if (link_info.s.speed == 1000)
560 reg_control.s.speed_msb = 1;
561 reg_control.s.speed_lsb = 0;
563 else if (link_info.s.speed == 100)
565 reg_control.s.speed_msb = 0;
566 reg_control.s.speed_lsb = 1;
568 else if (link_info.s.speed == 10)
570 reg_control.s.speed_msb = 0;
571 reg_control.s.speed_lsb = 0;
573 cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
581 * This function is called by cvmx_helper_interface_probe() after it
582 * determines the number of ports Octeon can support on a specific
583 * interface. This function is the per board location to override
584 * this value. It is called with the number of ports Octeon might
585 * support and should return the number of actual ports on the
588 * This function must be modifed for every new Octeon board.
589 * Internally it uses switch statements based on the cvmx_sysinfo
590 * data to determine board types and revisions. It relys on the
591 * fact that every Octeon board receives a unique board type
592 * enumeration from the bootloader.
594 * @param interface Interface to probe
595 * @param supported_ports
596 * Number of ports Octeon supports.
598 * @return Number of ports the actual board supports. Many times this will
599 * simple be "support_ports".
601 int __cvmx_helper_board_interface_probe(int interface, int supported_ports)
603 switch (cvmx_sysinfo_get()->board_type)
605 case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
609 case CVMX_BOARD_TYPE_BBGW_REF:
613 case CVMX_BOARD_TYPE_NIC_XLE_4G:
617 /* The 2nd interface on the EBH5600 is connected to the Marvel switch,
618 which we don't support. Disable ports connected to it */
619 case CVMX_BOARD_TYPE_EBH5600:
623 #if defined(OCTEON_VENDOR_LANNER)
624 case CVMX_BOARD_TYPE_CUST_LANNER_MR955:
630 #ifdef CVMX_BUILD_FOR_UBOOT
631 if (CVMX_HELPER_INTERFACE_MODE_SPI == cvmx_helper_interface_get_mode(interface) && getenv("disable_spi"))
634 return supported_ports;
640 * Enable packet input/output from the hardware. This function is
641 * called after by cvmx_helper_packet_hardware_enable() to
642 * perform board specific initialization. For most boards
645 * @param interface Interface to enable
647 * @return Zero on success, negative on failure
649 int __cvmx_helper_board_hardware_enable(int interface)
651 if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5)
655 /* Different config for switch port */
656 cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0);
657 cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
658 /* Boards with gigabit WAN ports need a different setting that is
659 compatible with 100 Mbit settings */
660 cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), 0xc);
661 cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), 0xc);
664 else if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3010_EVB_HS5)
666 /* Broadcom PHYs require differnet ASX clocks. Unfortunately
667 many customer don't define a new board Id and simply
668 mangle the CN3010_EVB_HS5 */
671 /* Some customers boards use a hacked up bootloader that identifies them as
672 ** CN3010_EVB_HS5 evaluation boards. This leads to all kinds of configuration
673 ** problems. Detect one case, and print warning, while trying to do the right thing.
675 int phy_addr = cvmx_helper_board_get_mii_address(0);
678 int phy_identifier = cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, 0x2);
679 /* Is it a Broadcom PHY? */
680 if (phy_identifier == 0x0143)
683 cvmx_dprintf("ERROR:\n");
684 cvmx_dprintf("ERROR: Board type is CVMX_BOARD_TYPE_CN3010_EVB_HS5, but Broadcom PHY found.\n");
685 cvmx_dprintf("ERROR: The board type is mis-configured, and software malfunctions are likely.\n");
686 cvmx_dprintf("ERROR: All boards require a unique board type to identify them.\n");
687 cvmx_dprintf("ERROR:\n");
689 cvmx_wait(1000000000);
690 cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), 5);
691 cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), 5);
699 cvmx_helper_board_usb_clock_types_t __cvmx_helper_board_usb_get_clock_type(void)
701 switch (cvmx_sysinfo_get()->board_type) {
702 case CVMX_BOARD_TYPE_BBGW_REF:
703 #if defined(OCTEON_VENDOR_LANNER)
704 case CVMX_BOARD_TYPE_CUST_LANNER_MR320:
706 return USB_CLOCK_TYPE_CRYSTAL_12;
708 return USB_CLOCK_TYPE_REF_48;
711 int __cvmx_helper_board_usb_get_num_ports(int supported_ports)
713 switch (cvmx_sysinfo_get()->board_type) {
714 case CVMX_BOARD_TYPE_NIC_XLE_4G:
718 return supported_ports;