1af866496SDavid Daney /***********************license start***************
2af866496SDavid Daney * Author: Cavium Networks
3af866496SDavid Daney *
4af866496SDavid Daney * Contact: support@caviumnetworks.com
5af866496SDavid Daney * This file is part of the OCTEON SDK
6af866496SDavid Daney *
7af866496SDavid Daney * Copyright (c) 2003-2008 Cavium Networks
8af866496SDavid Daney *
9af866496SDavid Daney * This file is free software; you can redistribute it and/or modify
10af866496SDavid Daney * it under the terms of the GNU General Public License, Version 2, as
11af866496SDavid Daney * published by the Free Software Foundation.
12af866496SDavid Daney *
13af866496SDavid Daney * This file is distributed in the hope that it will be useful, but
14af866496SDavid Daney * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15af866496SDavid Daney * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16af866496SDavid Daney * NONINFRINGEMENT. See the GNU General Public License for more
17af866496SDavid Daney * details.
18af866496SDavid Daney *
19af866496SDavid Daney * You should have received a copy of the GNU General Public License
20af866496SDavid Daney * along with this file; if not, write to the Free Software
21af866496SDavid Daney * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22af866496SDavid Daney * or visit http://www.gnu.org/licenses/.
23af866496SDavid Daney *
24af866496SDavid Daney * This file may also be available under a different license from Cavium.
25af866496SDavid Daney * Contact Cavium Networks for more information
26af866496SDavid Daney ***********************license end**************************************/
27af866496SDavid Daney
28af866496SDavid Daney /*
29af866496SDavid Daney *
30af866496SDavid Daney * Helper functions to abstract board specific data about
31af866496SDavid Daney * network ports from the rest of the cvmx-helper files.
32af866496SDavid Daney */
33af866496SDavid Daney
342c0756d3SAaro Koskinen #include <linux/bug.h>
35af866496SDavid Daney #include <asm/octeon/octeon.h>
36af866496SDavid Daney #include <asm/octeon/cvmx-bootinfo.h>
37af866496SDavid Daney
38af866496SDavid Daney #include <asm/octeon/cvmx-config.h>
39af866496SDavid Daney
40af866496SDavid Daney #include <asm/octeon/cvmx-helper.h>
41af866496SDavid Daney #include <asm/octeon/cvmx-helper-util.h>
42af866496SDavid Daney #include <asm/octeon/cvmx-helper-board.h>
43af866496SDavid Daney
44af866496SDavid Daney #include <asm/octeon/cvmx-gmxx-defs.h>
45af866496SDavid Daney #include <asm/octeon/cvmx-asxx-defs.h>
46af866496SDavid Daney
4716df55ceSRandy Dunlap /*
48af866496SDavid Daney * Return the MII PHY address associated with the given IPD
49af866496SDavid Daney * port. A result of -1 means there isn't a MII capable PHY
50af866496SDavid Daney * connected to this port. On chips supporting multiple MII
51af866496SDavid Daney * busses the bus number is encoded in bits <15:8>.
52af866496SDavid Daney *
53af866496SDavid Daney * This function must be modified for every new Octeon board.
54af866496SDavid Daney * Internally it uses switch statements based on the cvmx_sysinfo
55af866496SDavid Daney * data to determine board types and revisions. It replies on the
56af866496SDavid Daney * fact that every Octeon board receives a unique board type
57af866496SDavid Daney * enumeration from the bootloader.
58af866496SDavid Daney *
59af866496SDavid Daney * @ipd_port: Octeon IPD port to get the MII address for.
60af866496SDavid Daney *
61af866496SDavid Daney * Returns MII PHY address and bus number or -1.
62af866496SDavid Daney */
cvmx_helper_board_get_mii_address(int ipd_port)63af866496SDavid Daney int cvmx_helper_board_get_mii_address(int ipd_port)
64af866496SDavid Daney {
65af866496SDavid Daney switch (cvmx_sysinfo_get()->board_type) {
66af866496SDavid Daney case CVMX_BOARD_TYPE_SIM:
67af866496SDavid Daney /* Simulator doesn't have MII */
68af866496SDavid Daney return -1;
69af866496SDavid Daney case CVMX_BOARD_TYPE_EBT3000:
70af866496SDavid Daney case CVMX_BOARD_TYPE_EBT5800:
71af866496SDavid Daney case CVMX_BOARD_TYPE_THUNDER:
72af866496SDavid Daney case CVMX_BOARD_TYPE_NICPRO2:
73af866496SDavid Daney /* Interface 0 is SPI4, interface 1 is RGMII */
74af866496SDavid Daney if ((ipd_port >= 16) && (ipd_port < 20))
75af866496SDavid Daney return ipd_port - 16;
76af866496SDavid Daney else
77af866496SDavid Daney return -1;
78af866496SDavid Daney case CVMX_BOARD_TYPE_KODAMA:
79af866496SDavid Daney case CVMX_BOARD_TYPE_EBH3100:
80af866496SDavid Daney case CVMX_BOARD_TYPE_HIKARI:
81af866496SDavid Daney case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
82af866496SDavid Daney case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
83af866496SDavid Daney case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
84af866496SDavid Daney /*
85af866496SDavid Daney * Port 0 is WAN connected to a PHY, Port 1 is GMII
86af866496SDavid Daney * connected to a switch
87af866496SDavid Daney */
88af866496SDavid Daney if (ipd_port == 0)
89af866496SDavid Daney return 4;
90af866496SDavid Daney else if (ipd_port == 1)
91af866496SDavid Daney return 9;
92af866496SDavid Daney else
93af866496SDavid Daney return -1;
94af866496SDavid Daney case CVMX_BOARD_TYPE_NAC38:
95af866496SDavid Daney /* Board has 8 RGMII ports PHYs are 0-7 */
96af866496SDavid Daney if ((ipd_port >= 0) && (ipd_port < 4))
97af866496SDavid Daney return ipd_port;
98af866496SDavid Daney else if ((ipd_port >= 16) && (ipd_port < 20))
99af866496SDavid Daney return ipd_port - 16 + 4;
100af866496SDavid Daney else
101af866496SDavid Daney return -1;
102af866496SDavid Daney case CVMX_BOARD_TYPE_EBH3000:
103af866496SDavid Daney /* Board has dual SPI4 and no PHYs */
104af866496SDavid Daney return -1;
105af866496SDavid Daney case CVMX_BOARD_TYPE_EBH5200:
106af866496SDavid Daney case CVMX_BOARD_TYPE_EBH5201:
107af866496SDavid Daney case CVMX_BOARD_TYPE_EBT5200:
108ada11a33SDavid Daney /* Board has 2 management ports */
109ada11a33SDavid Daney if ((ipd_port >= CVMX_HELPER_BOARD_MGMT_IPD_PORT) &&
110ada11a33SDavid Daney (ipd_port < (CVMX_HELPER_BOARD_MGMT_IPD_PORT + 2)))
111ada11a33SDavid Daney return ipd_port - CVMX_HELPER_BOARD_MGMT_IPD_PORT;
112af866496SDavid Daney /*
113af866496SDavid Daney * Board has 4 SGMII ports. The PHYs start right after the MII
114af866496SDavid Daney * ports MII0 = 0, MII1 = 1, SGMII = 2-5.
115af866496SDavid Daney */
116af866496SDavid Daney if ((ipd_port >= 0) && (ipd_port < 4))
117af866496SDavid Daney return ipd_port + 2;
118af866496SDavid Daney else
119af866496SDavid Daney return -1;
120af866496SDavid Daney case CVMX_BOARD_TYPE_EBH5600:
121af866496SDavid Daney case CVMX_BOARD_TYPE_EBH5601:
122af866496SDavid Daney case CVMX_BOARD_TYPE_EBH5610:
123ada11a33SDavid Daney /* Board has 1 management port */
124ada11a33SDavid Daney if (ipd_port == CVMX_HELPER_BOARD_MGMT_IPD_PORT)
125ada11a33SDavid Daney return 0;
126af866496SDavid Daney /*
127af866496SDavid Daney * Board has 8 SGMII ports. 4 connect out, two connect
128af866496SDavid Daney * to a switch, and 2 loop to each other
129af866496SDavid Daney */
130af866496SDavid Daney if ((ipd_port >= 0) && (ipd_port < 4))
131af866496SDavid Daney return ipd_port + 1;
132af866496SDavid Daney else
133af866496SDavid Daney return -1;
134af866496SDavid Daney case CVMX_BOARD_TYPE_CUST_NB5:
135af866496SDavid Daney if (ipd_port == 2)
136af866496SDavid Daney return 4;
137af866496SDavid Daney else
138af866496SDavid Daney return -1;
139af866496SDavid Daney case CVMX_BOARD_TYPE_NIC_XLE_4G:
140af866496SDavid Daney /* Board has 4 SGMII ports. connected QLM3(interface 1) */
141af866496SDavid Daney if ((ipd_port >= 16) && (ipd_port < 20))
142af866496SDavid Daney return ipd_port - 16 + 1;
143af866496SDavid Daney else
144af866496SDavid Daney return -1;
145ada11a33SDavid Daney case CVMX_BOARD_TYPE_NIC_XLE_10G:
146ada11a33SDavid Daney case CVMX_BOARD_TYPE_NIC10E:
147ada11a33SDavid Daney return -1;
148ada11a33SDavid Daney case CVMX_BOARD_TYPE_NIC4E:
149ada11a33SDavid Daney if (ipd_port >= 0 && ipd_port <= 3)
150ada11a33SDavid Daney return (ipd_port + 0x1f) & 0x1f;
151ada11a33SDavid Daney else
152ada11a33SDavid Daney return -1;
153ada11a33SDavid Daney case CVMX_BOARD_TYPE_NIC2E:
154ada11a33SDavid Daney if (ipd_port >= 0 && ipd_port <= 1)
155ada11a33SDavid Daney return ipd_port + 1;
156ada11a33SDavid Daney else
157ada11a33SDavid Daney return -1;
158af866496SDavid Daney case CVMX_BOARD_TYPE_BBGW_REF:
159af866496SDavid Daney /*
160af866496SDavid Daney * No PHYs are connected to Octeon, everything is
161af866496SDavid Daney * through switch.
162af866496SDavid Daney */
163af866496SDavid Daney return -1;
164af866496SDavid Daney
165af866496SDavid Daney case CVMX_BOARD_TYPE_CUST_WSX16:
166af866496SDavid Daney if (ipd_port >= 0 && ipd_port <= 3)
167af866496SDavid Daney return ipd_port;
168af866496SDavid Daney else if (ipd_port >= 16 && ipd_port <= 19)
169af866496SDavid Daney return ipd_port - 16 + 4;
170af866496SDavid Daney else
171af866496SDavid Daney return -1;
172a135a9b5SAaro Koskinen case CVMX_BOARD_TYPE_UBNT_E100:
173a135a9b5SAaro Koskinen if (ipd_port >= 0 && ipd_port <= 2)
174a135a9b5SAaro Koskinen return 7 - ipd_port;
175a135a9b5SAaro Koskinen else
176a135a9b5SAaro Koskinen return -1;
177cef232ecSAaro Koskinen case CVMX_BOARD_TYPE_KONTRON_S1901:
178cef232ecSAaro Koskinen if (ipd_port == CVMX_HELPER_BOARD_MGMT_IPD_PORT)
179cef232ecSAaro Koskinen return 1;
180cef232ecSAaro Koskinen else
181cef232ecSAaro Koskinen return -1;
182cef232ecSAaro Koskinen
183af866496SDavid Daney }
184af866496SDavid Daney
185af866496SDavid Daney /* Some unknown board. Somebody forgot to update this function... */
186af866496SDavid Daney cvmx_dprintf
187af866496SDavid Daney ("cvmx_helper_board_get_mii_address: Unknown board type %d\n",
188af866496SDavid Daney cvmx_sysinfo_get()->board_type);
189af866496SDavid Daney return -1;
190af866496SDavid Daney }
191af866496SDavid Daney
19216df55ceSRandy Dunlap /*
193af866496SDavid Daney * This function is the board specific method of determining an
194af866496SDavid Daney * ethernet ports link speed. Most Octeon boards have Marvell PHYs
195af866496SDavid Daney * and are handled by the fall through case. This function must be
196af866496SDavid Daney * updated for boards that don't have the normal Marvell PHYs.
197af866496SDavid Daney *
198af866496SDavid Daney * This function must be modified for every new Octeon board.
199af866496SDavid Daney * Internally it uses switch statements based on the cvmx_sysinfo
200af866496SDavid Daney * data to determine board types and revisions. It relies on the
201af866496SDavid Daney * fact that every Octeon board receives a unique board type
202af866496SDavid Daney * enumeration from the bootloader.
203af866496SDavid Daney *
204af866496SDavid Daney * @ipd_port: IPD input port associated with the port we want to get link
205af866496SDavid Daney * status for.
206af866496SDavid Daney *
207af866496SDavid Daney * Returns The ports link status. If the link isn't fully resolved, this must
208af866496SDavid Daney * return zero.
209af866496SDavid Daney */
__cvmx_helper_board_link_get(int ipd_port)210f7d2bdcbSChris Packham union cvmx_helper_link_info __cvmx_helper_board_link_get(int ipd_port)
211af866496SDavid Daney {
212f7d2bdcbSChris Packham union cvmx_helper_link_info result;
213af866496SDavid Daney
214*4c587a98SLadislav Michl WARN_ONCE(!octeon_is_simulation(),
2152c0756d3SAaro Koskinen "Using deprecated link status - please update your DT");
2162c0756d3SAaro Koskinen
217af866496SDavid Daney /* Unless we fix it later, all links are defaulted to down */
218af866496SDavid Daney result.u64 = 0;
219af866496SDavid Daney
2201836c2b2SAaro Koskinen if (octeon_is_simulation()) {
221af866496SDavid Daney /* The simulator gives you a simulated 1Gbps full duplex link */
222af866496SDavid Daney result.s.link_up = 1;
223af866496SDavid Daney result.s.full_duplex = 1;
224af866496SDavid Daney result.s.speed = 1000;
225af866496SDavid Daney return result;
226af866496SDavid Daney }
227af866496SDavid Daney
2280d19672eSAaro Koskinen if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
229af866496SDavid Daney || OCTEON_IS_MODEL(OCTEON_CN58XX)
230af866496SDavid Daney || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
231af866496SDavid Daney /*
232af866496SDavid Daney * We don't have a PHY address, so attempt to use
233af866496SDavid Daney * in-band status. It is really important that boards
234af866496SDavid Daney * not supporting in-band status never get
235af866496SDavid Daney * here. Reading broken in-band status tends to do bad
236af866496SDavid Daney * things
237af866496SDavid Daney */
238af866496SDavid Daney union cvmx_gmxx_rxx_rx_inbnd inband_status;
239af866496SDavid Daney int interface = cvmx_helper_get_interface_num(ipd_port);
240af866496SDavid Daney int index = cvmx_helper_get_interface_index_num(ipd_port);
241af866496SDavid Daney inband_status.u64 =
242af866496SDavid Daney cvmx_read_csr(CVMX_GMXX_RXX_RX_INBND(index, interface));
243af866496SDavid Daney
244af866496SDavid Daney result.s.link_up = inband_status.s.status;
245af866496SDavid Daney result.s.full_duplex = inband_status.s.duplex;
246af866496SDavid Daney switch (inband_status.s.speed) {
247af866496SDavid Daney case 0: /* 10 Mbps */
248af866496SDavid Daney result.s.speed = 10;
249af866496SDavid Daney break;
250af866496SDavid Daney case 1: /* 100 Mbps */
251af866496SDavid Daney result.s.speed = 100;
252af866496SDavid Daney break;
253af866496SDavid Daney case 2: /* 1 Gbps */
254af866496SDavid Daney result.s.speed = 1000;
255af866496SDavid Daney break;
256af866496SDavid Daney case 3: /* Illegal */
257af866496SDavid Daney result.u64 = 0;
258af866496SDavid Daney break;
259af866496SDavid Daney }
260af866496SDavid Daney } else {
261af866496SDavid Daney /*
262af866496SDavid Daney * We don't have a PHY address and we don't have
263af866496SDavid Daney * in-band status. There is no way to determine the
264af866496SDavid Daney * link speed. Return down assuming this port isn't
265af866496SDavid Daney * wired
266af866496SDavid Daney */
267af866496SDavid Daney result.u64 = 0;
268af866496SDavid Daney }
269af866496SDavid Daney
270af866496SDavid Daney /* If link is down, return all fields as zero. */
271af866496SDavid Daney if (!result.s.link_up)
272af866496SDavid Daney result.u64 = 0;
273af866496SDavid Daney
274af866496SDavid Daney return result;
275af866496SDavid Daney }
276af866496SDavid Daney
27716df55ceSRandy Dunlap /*
278af866496SDavid Daney * This function is called by cvmx_helper_interface_probe() after it
279af866496SDavid Daney * determines the number of ports Octeon can support on a specific
280af866496SDavid Daney * interface. This function is the per board location to override
281af866496SDavid Daney * this value. It is called with the number of ports Octeon might
282af866496SDavid Daney * support and should return the number of actual ports on the
283af866496SDavid Daney * board.
284af866496SDavid Daney *
2855e1138c6SZhang Jiaming * This function must be modified for every new Octeon board.
286af866496SDavid Daney * Internally it uses switch statements based on the cvmx_sysinfo
2875e1138c6SZhang Jiaming * data to determine board types and revisions. It relies on the
288af866496SDavid Daney * fact that every Octeon board receives a unique board type
289af866496SDavid Daney * enumeration from the bootloader.
290af866496SDavid Daney *
291af866496SDavid Daney * @interface: Interface to probe
292af866496SDavid Daney * @supported_ports:
293af866496SDavid Daney * Number of ports Octeon supports.
294af866496SDavid Daney *
295af866496SDavid Daney * Returns Number of ports the actual board supports. Many times this will
296af866496SDavid Daney * simple be "support_ports".
297af866496SDavid Daney */
__cvmx_helper_board_interface_probe(int interface,int supported_ports)298af866496SDavid Daney int __cvmx_helper_board_interface_probe(int interface, int supported_ports)
299af866496SDavid Daney {
300af866496SDavid Daney switch (cvmx_sysinfo_get()->board_type) {
301af866496SDavid Daney case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
302af866496SDavid Daney if (interface == 0)
303af866496SDavid Daney return 2;
304af866496SDavid Daney break;
305af866496SDavid Daney case CVMX_BOARD_TYPE_BBGW_REF:
306af866496SDavid Daney if (interface == 0)
307af866496SDavid Daney return 2;
308af866496SDavid Daney break;
309af866496SDavid Daney case CVMX_BOARD_TYPE_NIC_XLE_4G:
310af866496SDavid Daney if (interface == 0)
311af866496SDavid Daney return 0;
312af866496SDavid Daney break;
313af866496SDavid Daney /* The 2nd interface on the EBH5600 is connected to the Marvel switch,
314af866496SDavid Daney which we don't support. Disable ports connected to it */
315af866496SDavid Daney case CVMX_BOARD_TYPE_EBH5600:
316af866496SDavid Daney if (interface == 1)
317af866496SDavid Daney return 0;
318af866496SDavid Daney break;
319af866496SDavid Daney }
320af866496SDavid Daney return supported_ports;
321af866496SDavid Daney }
322af866496SDavid Daney
32316df55ceSRandy Dunlap /*
324d617f9e9SDavid Daney * Get the clock type used for the USB block based on board type.
325d617f9e9SDavid Daney * Used by the USB code for auto configuration of clock type.
326d617f9e9SDavid Daney *
327d617f9e9SDavid Daney * Return USB clock type enumeration
328d617f9e9SDavid Daney */
__cvmx_helper_board_usb_get_clock_type(void)329d617f9e9SDavid Daney enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void)
330d617f9e9SDavid Daney {
331d617f9e9SDavid Daney switch (cvmx_sysinfo_get()->board_type) {
332d617f9e9SDavid Daney case CVMX_BOARD_TYPE_BBGW_REF:
333d617f9e9SDavid Daney case CVMX_BOARD_TYPE_LANAI2_A:
334d617f9e9SDavid Daney case CVMX_BOARD_TYPE_LANAI2_U:
335d617f9e9SDavid Daney case CVMX_BOARD_TYPE_LANAI2_G:
336d617f9e9SDavid Daney case CVMX_BOARD_TYPE_NIC10E_66:
337d617f9e9SDavid Daney case CVMX_BOARD_TYPE_UBNT_E100:
338d617f9e9SDavid Daney return USB_CLOCK_TYPE_CRYSTAL_12;
339d617f9e9SDavid Daney case CVMX_BOARD_TYPE_NIC10E:
340d617f9e9SDavid Daney return USB_CLOCK_TYPE_REF_12;
341d617f9e9SDavid Daney default:
342d617f9e9SDavid Daney break;
343d617f9e9SDavid Daney }
344d617f9e9SDavid Daney /* Most boards except NIC10e use a 12MHz crystal */
345debe6a62SDavid Daney if (OCTEON_IS_OCTEON2())
346d617f9e9SDavid Daney return USB_CLOCK_TYPE_CRYSTAL_12;
347d617f9e9SDavid Daney return USB_CLOCK_TYPE_REF_48;
348d617f9e9SDavid Daney }
349