1 /***********************license start***************
2  * Author: Cavium Networks
3  *
4  * Contact: support@caviumnetworks.com
5  * This file is part of the OCTEON SDK
6  *
7  * Copyright (c) 2003-2008 Cavium Networks
8  *
9  * This file is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License, Version 2, as
11  * published by the Free Software Foundation.
12  *
13  * This file is distributed in the hope that it will be useful, but
14  * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16  * NONINFRINGEMENT.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this file; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22  * or visit http://www.gnu.org/licenses/.
23  *
24  * This file may also be available under a different license from Cavium.
25  * Contact Cavium Networks for more information
26  ***********************license end**************************************/
27 
28 /*
29  *
30  * Helper functions for common, but complicated tasks.
31  *
32  */
33 #include <asm/octeon/octeon.h>
34 
35 #include <asm/octeon/cvmx-config.h>
36 
37 #include <asm/octeon/cvmx-fpa.h>
38 #include <asm/octeon/cvmx-pip.h>
39 #include <asm/octeon/cvmx-pko.h>
40 #include <asm/octeon/cvmx-ipd.h>
41 #include <asm/octeon/cvmx-spi.h>
42 #include <asm/octeon/cvmx-helper.h>
43 #include <asm/octeon/cvmx-helper-board.h>
44 
45 #include <asm/octeon/cvmx-pip-defs.h>
46 #include <asm/octeon/cvmx-smix-defs.h>
47 #include <asm/octeon/cvmx-asxx-defs.h>
48 
49 /* Port count per interface */
50 static int interface_port_count[9];
51 
52 /**
53  * Return the number of interfaces the chip has. Each interface
54  * may have multiple ports. Most chips support two interfaces,
55  * but the CNX0XX and CNX1XX are exceptions. These only support
56  * one interface.
57  *
58  * Returns Number of interfaces on chip
59  */
60 int cvmx_helper_get_number_of_interfaces(void)
61 {
62 	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
63 		return 9;
64 	if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
65 		return 4;
66 	if (OCTEON_IS_MODEL(OCTEON_CN7XXX))
67 		return 5;
68 	else
69 		return 3;
70 }
71 EXPORT_SYMBOL_GPL(cvmx_helper_get_number_of_interfaces);
72 
73 /**
74  * Return the number of ports on an interface. Depending on the
75  * chip and configuration, this can be 1-16. A value of 0
76  * specifies that the interface doesn't exist or isn't usable.
77  *
78  * @interface: Interface to get the port count for
79  *
80  * Returns Number of ports on interface. Can be Zero.
81  */
82 int cvmx_helper_ports_on_interface(int interface)
83 {
84 	return interface_port_count[interface];
85 }
86 EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface);
87 
88 /**
89  * @INTERNAL
90  * Return interface mode for CN68xx.
91  */
92 static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface)
93 {
94 	union cvmx_mio_qlmx_cfg qlm_cfg;
95 	switch (interface) {
96 	case 0:
97 		qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
98 		/* QLM is disabled when QLM SPD is 15. */
99 		if (qlm_cfg.s.qlm_spd == 15)
100 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
101 
102 		if (qlm_cfg.s.qlm_cfg == 2)
103 			return CVMX_HELPER_INTERFACE_MODE_SGMII;
104 		else if (qlm_cfg.s.qlm_cfg == 3)
105 			return CVMX_HELPER_INTERFACE_MODE_XAUI;
106 		else
107 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
108 	case 2:
109 	case 3:
110 	case 4:
111 		qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(interface));
112 		/* QLM is disabled when QLM SPD is 15. */
113 		if (qlm_cfg.s.qlm_spd == 15)
114 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
115 
116 		if (qlm_cfg.s.qlm_cfg == 2)
117 			return CVMX_HELPER_INTERFACE_MODE_SGMII;
118 		else if (qlm_cfg.s.qlm_cfg == 3)
119 			return CVMX_HELPER_INTERFACE_MODE_XAUI;
120 		else
121 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
122 	case 7:
123 		qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(3));
124 		/* QLM is disabled when QLM SPD is 15. */
125 		if (qlm_cfg.s.qlm_spd == 15) {
126 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
127 		} else if (qlm_cfg.s.qlm_cfg != 0) {
128 			qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
129 			if (qlm_cfg.s.qlm_cfg != 0)
130 				return CVMX_HELPER_INTERFACE_MODE_DISABLED;
131 		}
132 		return CVMX_HELPER_INTERFACE_MODE_NPI;
133 	case 8:
134 		return CVMX_HELPER_INTERFACE_MODE_LOOP;
135 	default:
136 		return CVMX_HELPER_INTERFACE_MODE_DISABLED;
137 	}
138 }
139 
140 /**
141  * @INTERNAL
142  * Return interface mode for an Octeon II
143  */
144 static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)
145 {
146 	union cvmx_gmxx_inf_mode mode;
147 
148 	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
149 		return __cvmx_get_mode_cn68xx(interface);
150 
151 	if (interface == 2)
152 		return CVMX_HELPER_INTERFACE_MODE_NPI;
153 
154 	if (interface == 3)
155 		return CVMX_HELPER_INTERFACE_MODE_LOOP;
156 
157 	/* Only present in CN63XX & CN66XX Octeon model */
158 	if ((OCTEON_IS_MODEL(OCTEON_CN63XX) &&
159 	     (interface == 4 || interface == 5)) ||
160 	    (OCTEON_IS_MODEL(OCTEON_CN66XX) &&
161 	     interface >= 4 && interface <= 7)) {
162 		return CVMX_HELPER_INTERFACE_MODE_DISABLED;
163 	}
164 
165 	if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
166 		union cvmx_mio_qlmx_cfg mio_qlm_cfg;
167 
168 		/* QLM2 is SGMII0 and QLM1 is SGMII1 */
169 		if (interface == 0)
170 			mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
171 		else if (interface == 1)
172 			mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
173 		else
174 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
175 
176 		if (mio_qlm_cfg.s.qlm_spd == 15)
177 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
178 
179 		if (mio_qlm_cfg.s.qlm_cfg == 9)
180 			return CVMX_HELPER_INTERFACE_MODE_SGMII;
181 		else if (mio_qlm_cfg.s.qlm_cfg == 11)
182 			return CVMX_HELPER_INTERFACE_MODE_XAUI;
183 		else
184 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
185 	} else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) {
186 		union cvmx_mio_qlmx_cfg qlm_cfg;
187 
188 		if (interface == 0) {
189 			qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
190 			if (qlm_cfg.s.qlm_cfg == 2)
191 				return CVMX_HELPER_INTERFACE_MODE_SGMII;
192 			else if (qlm_cfg.s.qlm_cfg == 3)
193 				return CVMX_HELPER_INTERFACE_MODE_XAUI;
194 			else
195 				return CVMX_HELPER_INTERFACE_MODE_DISABLED;
196 		} else if (interface == 1) {
197 			qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
198 			if (qlm_cfg.s.qlm_cfg == 2)
199 				return CVMX_HELPER_INTERFACE_MODE_SGMII;
200 			else if (qlm_cfg.s.qlm_cfg == 3)
201 				return CVMX_HELPER_INTERFACE_MODE_XAUI;
202 			else
203 				return CVMX_HELPER_INTERFACE_MODE_DISABLED;
204 		}
205 	} else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) {
206 		if (interface == 0) {
207 			union cvmx_mio_qlmx_cfg qlm_cfg;
208 			qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
209 			if (qlm_cfg.s.qlm_cfg == 2)
210 				return CVMX_HELPER_INTERFACE_MODE_SGMII;
211 		}
212 		return CVMX_HELPER_INTERFACE_MODE_DISABLED;
213 	}
214 
215 	if (interface == 1 && OCTEON_IS_MODEL(OCTEON_CN63XX))
216 		return CVMX_HELPER_INTERFACE_MODE_DISABLED;
217 
218 	mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
219 
220 	if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
221 		switch (mode.cn61xx.mode) {
222 		case 0:
223 			return CVMX_HELPER_INTERFACE_MODE_SGMII;
224 		case 1:
225 			return CVMX_HELPER_INTERFACE_MODE_XAUI;
226 		default:
227 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
228 		}
229 	} else {
230 		if (!mode.s.en)
231 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
232 
233 		if (mode.s.type)
234 			return CVMX_HELPER_INTERFACE_MODE_GMII;
235 		else
236 			return CVMX_HELPER_INTERFACE_MODE_RGMII;
237 	}
238 }
239 
240 /**
241  * @INTERNAL
242  * Return interface mode for CN7XXX.
243  */
244 static cvmx_helper_interface_mode_t __cvmx_get_mode_cn7xxx(int interface)
245 {
246 	union cvmx_gmxx_inf_mode mode;
247 
248 	mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
249 
250 	switch (interface) {
251 	case 0:
252 	case 1:
253 		switch (mode.cn68xx.mode) {
254 		case 0:
255 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
256 		case 1:
257 		case 2:
258 			return CVMX_HELPER_INTERFACE_MODE_SGMII;
259 		case 3:
260 			return CVMX_HELPER_INTERFACE_MODE_XAUI;
261 		default:
262 			return CVMX_HELPER_INTERFACE_MODE_SGMII;
263 		}
264 	case 2:
265 		return CVMX_HELPER_INTERFACE_MODE_NPI;
266 	case 3:
267 		return CVMX_HELPER_INTERFACE_MODE_LOOP;
268 	case 4:
269 		/* TODO: Implement support for AGL (RGMII). */
270 		return CVMX_HELPER_INTERFACE_MODE_DISABLED;
271 	default:
272 		return CVMX_HELPER_INTERFACE_MODE_DISABLED;
273 	}
274 }
275 
276 /**
277  * Get the operating mode of an interface. Depending on the Octeon
278  * chip and configuration, this function returns an enumeration
279  * of the type of packet I/O supported by an interface.
280  *
281  * @interface: Interface to probe
282  *
283  * Returns Mode of the interface. Unknown or unsupported interfaces return
284  *	   DISABLED.
285  */
286 cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
287 {
288 	union cvmx_gmxx_inf_mode mode;
289 
290 	if (interface < 0 ||
291 	    interface >= cvmx_helper_get_number_of_interfaces())
292 		return CVMX_HELPER_INTERFACE_MODE_DISABLED;
293 
294 	/*
295 	 * OCTEON III models
296 	 */
297 	if (OCTEON_IS_MODEL(OCTEON_CN7XXX))
298 		return __cvmx_get_mode_cn7xxx(interface);
299 
300 	/*
301 	 * Octeon II models
302 	 */
303 	if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
304 		return __cvmx_get_mode_octeon2(interface);
305 
306 	/*
307 	 * Octeon and Octeon Plus models
308 	 */
309 	if (interface == 2)
310 		return CVMX_HELPER_INTERFACE_MODE_NPI;
311 
312 	if (interface == 3) {
313 		if (OCTEON_IS_MODEL(OCTEON_CN56XX)
314 		    || OCTEON_IS_MODEL(OCTEON_CN52XX))
315 			return CVMX_HELPER_INTERFACE_MODE_LOOP;
316 		else
317 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
318 	}
319 
320 	if (interface == 0
321 	    && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5
322 	    && cvmx_sysinfo_get()->board_rev_major == 1) {
323 		/*
324 		 * Lie about interface type of CN3005 board.  This
325 		 * board has a switch on port 1 like the other
326 		 * evaluation boards, but it is connected over RGMII
327 		 * instead of GMII.  Report GMII mode so that the
328 		 * speed is forced to 1 Gbit full duplex.  Other than
329 		 * some initial configuration (which does not use the
330 		 * output of this function) there is no difference in
331 		 * setup between GMII and RGMII modes.
332 		 */
333 		return CVMX_HELPER_INTERFACE_MODE_GMII;
334 	}
335 
336 	/* Interface 1 is always disabled on CN31XX and CN30XX */
337 	if ((interface == 1)
338 	    && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX)
339 		|| OCTEON_IS_MODEL(OCTEON_CN50XX)
340 		|| OCTEON_IS_MODEL(OCTEON_CN52XX)))
341 		return CVMX_HELPER_INTERFACE_MODE_DISABLED;
342 
343 	mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
344 
345 	if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
346 		switch (mode.cn52xx.mode) {
347 		case 0:
348 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
349 		case 1:
350 			return CVMX_HELPER_INTERFACE_MODE_XAUI;
351 		case 2:
352 			return CVMX_HELPER_INTERFACE_MODE_SGMII;
353 		case 3:
354 			return CVMX_HELPER_INTERFACE_MODE_PICMG;
355 		default:
356 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
357 		}
358 	} else {
359 		if (!mode.s.en)
360 			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
361 
362 		if (mode.s.type) {
363 			if (OCTEON_IS_MODEL(OCTEON_CN38XX)
364 			    || OCTEON_IS_MODEL(OCTEON_CN58XX))
365 				return CVMX_HELPER_INTERFACE_MODE_SPI;
366 			else
367 				return CVMX_HELPER_INTERFACE_MODE_GMII;
368 		} else
369 			return CVMX_HELPER_INTERFACE_MODE_RGMII;
370 	}
371 }
372 EXPORT_SYMBOL_GPL(cvmx_helper_interface_get_mode);
373 
374 /**
375  * Configure the IPD/PIP tagging and QoS options for a specific
376  * port. This function determines the POW work queue entry
377  * contents for a port. The setup performed here is controlled by
378  * the defines in executive-config.h.
379  *
380  * @ipd_port: Port to configure. This follows the IPD numbering, not the
381  *		   per interface numbering
382  *
383  * Returns Zero on success, negative on failure
384  */
385 static int __cvmx_helper_port_setup_ipd(int ipd_port)
386 {
387 	union cvmx_pip_prt_cfgx port_config;
388 	union cvmx_pip_prt_tagx tag_config;
389 
390 	port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
391 	tag_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port));
392 
393 	/* Have each port go to a different POW queue */
394 	port_config.s.qos = ipd_port & 0x7;
395 
396 	/* Process the headers and place the IP header in the work queue */
397 	port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE;
398 
399 	tag_config.s.ip6_src_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP;
400 	tag_config.s.ip6_dst_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_IP;
401 	tag_config.s.ip6_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT;
402 	tag_config.s.ip6_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT;
403 	tag_config.s.ip6_nxth_flag = CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER;
404 	tag_config.s.ip4_src_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP;
405 	tag_config.s.ip4_dst_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_IP;
406 	tag_config.s.ip4_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT;
407 	tag_config.s.ip4_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT;
408 	tag_config.s.ip4_pctl_flag = CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL;
409 	tag_config.s.inc_prt_flag = CVMX_HELPER_INPUT_TAG_INPUT_PORT;
410 	tag_config.s.tcp6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
411 	tag_config.s.tcp4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
412 	tag_config.s.ip6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
413 	tag_config.s.ip4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
414 	tag_config.s.non_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
415 	/* Put all packets in group 0. Other groups can be used by the app */
416 	tag_config.s.grp = 0;
417 
418 	cvmx_pip_config_port(ipd_port, port_config, tag_config);
419 
420 	return 0;
421 }
422 
423 /**
424  * This function sets the interface_port_count[interface] correctly,
425  * without modifying any hardware configuration.  Hardware setup of
426  * the ports will be performed later.
427  *
428  * @interface: Interface to probe
429  *
430  * Returns Zero on success, negative on failure
431  */
432 int cvmx_helper_interface_enumerate(int interface)
433 {
434 	switch (cvmx_helper_interface_get_mode(interface)) {
435 		/* These types don't support ports to IPD/PKO */
436 	case CVMX_HELPER_INTERFACE_MODE_DISABLED:
437 	case CVMX_HELPER_INTERFACE_MODE_PCIE:
438 		interface_port_count[interface] = 0;
439 		break;
440 		/* XAUI is a single high speed port */
441 	case CVMX_HELPER_INTERFACE_MODE_XAUI:
442 		interface_port_count[interface] =
443 		    __cvmx_helper_xaui_enumerate(interface);
444 		break;
445 		/*
446 		 * RGMII/GMII/MII are all treated about the same. Most
447 		 * functions refer to these ports as RGMII.
448 		 */
449 	case CVMX_HELPER_INTERFACE_MODE_RGMII:
450 	case CVMX_HELPER_INTERFACE_MODE_GMII:
451 		interface_port_count[interface] =
452 		    __cvmx_helper_rgmii_enumerate(interface);
453 		break;
454 		/*
455 		 * SPI4 can have 1-16 ports depending on the device at
456 		 * the other end.
457 		 */
458 	case CVMX_HELPER_INTERFACE_MODE_SPI:
459 		interface_port_count[interface] =
460 		    __cvmx_helper_spi_enumerate(interface);
461 		break;
462 		/*
463 		 * SGMII can have 1-4 ports depending on how many are
464 		 * hooked up.
465 		 */
466 	case CVMX_HELPER_INTERFACE_MODE_SGMII:
467 	case CVMX_HELPER_INTERFACE_MODE_PICMG:
468 		interface_port_count[interface] =
469 		    __cvmx_helper_sgmii_enumerate(interface);
470 		break;
471 		/* PCI target Network Packet Interface */
472 	case CVMX_HELPER_INTERFACE_MODE_NPI:
473 		interface_port_count[interface] =
474 		    __cvmx_helper_npi_enumerate(interface);
475 		break;
476 		/*
477 		 * Special loopback only ports. These are not the same
478 		 * as other ports in loopback mode.
479 		 */
480 	case CVMX_HELPER_INTERFACE_MODE_LOOP:
481 		interface_port_count[interface] =
482 		    __cvmx_helper_loop_enumerate(interface);
483 		break;
484 	}
485 
486 	interface_port_count[interface] =
487 	    __cvmx_helper_board_interface_probe(interface,
488 						interface_port_count
489 						[interface]);
490 
491 	/* Make sure all global variables propagate to other cores */
492 	CVMX_SYNCWS;
493 
494 	return 0;
495 }
496 
497 /**
498  * This function probes an interface to determine the actual
499  * number of hardware ports connected to it. It doesn't setup the
500  * ports or enable them. The main goal here is to set the global
501  * interface_port_count[interface] correctly. Hardware setup of the
502  * ports will be performed later.
503  *
504  * @interface: Interface to probe
505  *
506  * Returns Zero on success, negative on failure
507  */
508 int cvmx_helper_interface_probe(int interface)
509 {
510 	cvmx_helper_interface_enumerate(interface);
511 	/* At this stage in the game we don't want packets to be moving yet.
512 	   The following probe calls should perform hardware setup
513 	   needed to determine port counts. Receive must still be disabled */
514 	switch (cvmx_helper_interface_get_mode(interface)) {
515 		/* These types don't support ports to IPD/PKO */
516 	case CVMX_HELPER_INTERFACE_MODE_DISABLED:
517 	case CVMX_HELPER_INTERFACE_MODE_PCIE:
518 		break;
519 		/* XAUI is a single high speed port */
520 	case CVMX_HELPER_INTERFACE_MODE_XAUI:
521 		__cvmx_helper_xaui_probe(interface);
522 		break;
523 		/*
524 		 * RGMII/GMII/MII are all treated about the same. Most
525 		 * functions refer to these ports as RGMII.
526 		 */
527 	case CVMX_HELPER_INTERFACE_MODE_RGMII:
528 	case CVMX_HELPER_INTERFACE_MODE_GMII:
529 		__cvmx_helper_rgmii_probe(interface);
530 		break;
531 		/*
532 		 * SPI4 can have 1-16 ports depending on the device at
533 		 * the other end.
534 		 */
535 	case CVMX_HELPER_INTERFACE_MODE_SPI:
536 		__cvmx_helper_spi_probe(interface);
537 		break;
538 		/*
539 		 * SGMII can have 1-4 ports depending on how many are
540 		 * hooked up.
541 		 */
542 	case CVMX_HELPER_INTERFACE_MODE_SGMII:
543 	case CVMX_HELPER_INTERFACE_MODE_PICMG:
544 		__cvmx_helper_sgmii_probe(interface);
545 		break;
546 		/* PCI target Network Packet Interface */
547 	case CVMX_HELPER_INTERFACE_MODE_NPI:
548 		__cvmx_helper_npi_probe(interface);
549 		break;
550 		/*
551 		 * Special loopback only ports. These are not the same
552 		 * as other ports in loopback mode.
553 		 */
554 	case CVMX_HELPER_INTERFACE_MODE_LOOP:
555 		__cvmx_helper_loop_probe(interface);
556 		break;
557 	}
558 
559 	/* Make sure all global variables propagate to other cores */
560 	CVMX_SYNCWS;
561 
562 	return 0;
563 }
564 
565 /**
566  * Setup the IPD/PIP for the ports on an interface. Packet
567  * classification and tagging are set for every port on the
568  * interface. The number of ports on the interface must already
569  * have been probed.
570  *
571  * @interface: Interface to setup IPD/PIP for
572  *
573  * Returns Zero on success, negative on failure
574  */
575 static int __cvmx_helper_interface_setup_ipd(int interface)
576 {
577 	int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
578 	int num_ports = interface_port_count[interface];
579 
580 	while (num_ports--) {
581 		__cvmx_helper_port_setup_ipd(ipd_port);
582 		ipd_port++;
583 	}
584 	return 0;
585 }
586 
587 /**
588  * Setup global setting for IPD/PIP not related to a specific
589  * interface or port. This must be called before IPD is enabled.
590  *
591  * Returns Zero on success, negative on failure.
592  */
593 static int __cvmx_helper_global_setup_ipd(void)
594 {
595 	/* Setup the global packet input options */
596 	cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE / 8,
597 			CVMX_HELPER_FIRST_MBUFF_SKIP / 8,
598 			CVMX_HELPER_NOT_FIRST_MBUFF_SKIP / 8,
599 			/* The +8 is to account for the next ptr */
600 			(CVMX_HELPER_FIRST_MBUFF_SKIP + 8) / 128,
601 			/* The +8 is to account for the next ptr */
602 			(CVMX_HELPER_NOT_FIRST_MBUFF_SKIP + 8) / 128,
603 			CVMX_FPA_WQE_POOL,
604 			CVMX_IPD_OPC_MODE_STT,
605 			CVMX_HELPER_ENABLE_BACK_PRESSURE);
606 	return 0;
607 }
608 
609 /**
610  * Setup the PKO for the ports on an interface. The number of
611  * queues per port and the priority of each PKO output queue
612  * is set here. PKO must be disabled when this function is called.
613  *
614  * @interface: Interface to setup PKO for
615  *
616  * Returns Zero on success, negative on failure
617  */
618 static int __cvmx_helper_interface_setup_pko(int interface)
619 {
620 	/*
621 	 * Each packet output queue has an associated priority. The
622 	 * higher the priority, the more often it can send a packet. A
623 	 * priority of 8 means it can send in all 8 rounds of
624 	 * contention. We're going to make each queue one less than
625 	 * the last.  The vector of priorities has been extended to
626 	 * support CN5xxx CPUs, where up to 16 queues can be
627 	 * associated to a port.  To keep backward compatibility we
628 	 * don't change the initial 8 priorities and replicate them in
629 	 * the second half.  With per-core PKO queues (PKO lockless
630 	 * operation) all queues have the same priority.
631 	 */
632 	uint64_t priorities[16] =
633 	    { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 };
634 
635 	/*
636 	 * Setup the IPD/PIP and PKO for the ports discovered
637 	 * above. Here packet classification, tagging and output
638 	 * priorities are set.
639 	 */
640 	int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
641 	int num_ports = interface_port_count[interface];
642 	while (num_ports--) {
643 		cvmx_pko_config_port(ipd_port,
644 				     cvmx_pko_get_base_queue_per_core(ipd_port,
645 								      0),
646 				     cvmx_pko_get_num_queues(ipd_port),
647 				     priorities);
648 		ipd_port++;
649 	}
650 	return 0;
651 }
652 
653 /**
654  * Setup global setting for PKO not related to a specific
655  * interface or port. This must be called before PKO is enabled.
656  *
657  * Returns Zero on success, negative on failure.
658  */
659 static int __cvmx_helper_global_setup_pko(void)
660 {
661 	/*
662 	 * Disable tagwait FAU timeout. This needs to be done before
663 	 * anyone might start packet output using tags.
664 	 */
665 	union cvmx_iob_fau_timeout fau_to;
666 	fau_to.u64 = 0;
667 	fau_to.s.tout_val = 0xfff;
668 	fau_to.s.tout_enb = 0;
669 	cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64);
670 
671 	if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
672 		union cvmx_pko_reg_min_pkt min_pkt;
673 
674 		min_pkt.u64 = 0;
675 		min_pkt.s.size1 = 59;
676 		min_pkt.s.size2 = 59;
677 		min_pkt.s.size3 = 59;
678 		min_pkt.s.size4 = 59;
679 		min_pkt.s.size5 = 59;
680 		min_pkt.s.size6 = 59;
681 		min_pkt.s.size7 = 59;
682 		cvmx_write_csr(CVMX_PKO_REG_MIN_PKT, min_pkt.u64);
683 	}
684 
685 	return 0;
686 }
687 
688 /**
689  * Setup global backpressure setting.
690  *
691  * Returns Zero on success, negative on failure
692  */
693 static int __cvmx_helper_global_setup_backpressure(void)
694 {
695 #if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE
696 	/* Disable backpressure if configured to do so */
697 	/* Disable backpressure (pause frame) generation */
698 	int num_interfaces = cvmx_helper_get_number_of_interfaces();
699 	int interface;
700 	for (interface = 0; interface < num_interfaces; interface++) {
701 		switch (cvmx_helper_interface_get_mode(interface)) {
702 		case CVMX_HELPER_INTERFACE_MODE_DISABLED:
703 		case CVMX_HELPER_INTERFACE_MODE_PCIE:
704 		case CVMX_HELPER_INTERFACE_MODE_NPI:
705 		case CVMX_HELPER_INTERFACE_MODE_LOOP:
706 		case CVMX_HELPER_INTERFACE_MODE_XAUI:
707 			break;
708 		case CVMX_HELPER_INTERFACE_MODE_RGMII:
709 		case CVMX_HELPER_INTERFACE_MODE_GMII:
710 		case CVMX_HELPER_INTERFACE_MODE_SPI:
711 		case CVMX_HELPER_INTERFACE_MODE_SGMII:
712 		case CVMX_HELPER_INTERFACE_MODE_PICMG:
713 			cvmx_gmx_set_backpressure_override(interface, 0xf);
714 			break;
715 		}
716 	}
717 #endif
718 
719 	return 0;
720 }
721 
722 /**
723  * Enable packet input/output from the hardware. This function is
724  * called after all internal setup is complete and IPD is enabled.
725  * After this function completes, packets will be accepted from the
726  * hardware ports. PKO should still be disabled to make sure packets
727  * aren't sent out partially setup hardware.
728  *
729  * @interface: Interface to enable
730  *
731  * Returns Zero on success, negative on failure
732  */
733 static int __cvmx_helper_packet_hardware_enable(int interface)
734 {
735 	int result = 0;
736 	switch (cvmx_helper_interface_get_mode(interface)) {
737 		/* These types don't support ports to IPD/PKO */
738 	case CVMX_HELPER_INTERFACE_MODE_DISABLED:
739 	case CVMX_HELPER_INTERFACE_MODE_PCIE:
740 		/* Nothing to do */
741 		break;
742 		/* XAUI is a single high speed port */
743 	case CVMX_HELPER_INTERFACE_MODE_XAUI:
744 		result = __cvmx_helper_xaui_enable(interface);
745 		break;
746 		/*
747 		 * RGMII/GMII/MII are all treated about the same. Most
748 		 * functions refer to these ports as RGMII
749 		 */
750 	case CVMX_HELPER_INTERFACE_MODE_RGMII:
751 	case CVMX_HELPER_INTERFACE_MODE_GMII:
752 		result = __cvmx_helper_rgmii_enable(interface);
753 		break;
754 		/*
755 		 * SPI4 can have 1-16 ports depending on the device at
756 		 * the other end
757 		 */
758 	case CVMX_HELPER_INTERFACE_MODE_SPI:
759 		result = __cvmx_helper_spi_enable(interface);
760 		break;
761 		/*
762 		 * SGMII can have 1-4 ports depending on how many are
763 		 * hooked up
764 		 */
765 	case CVMX_HELPER_INTERFACE_MODE_SGMII:
766 	case CVMX_HELPER_INTERFACE_MODE_PICMG:
767 		result = __cvmx_helper_sgmii_enable(interface);
768 		break;
769 		/* PCI target Network Packet Interface */
770 	case CVMX_HELPER_INTERFACE_MODE_NPI:
771 		result = __cvmx_helper_npi_enable(interface);
772 		break;
773 		/*
774 		 * Special loopback only ports. These are not the same
775 		 * as other ports in loopback mode
776 		 */
777 	case CVMX_HELPER_INTERFACE_MODE_LOOP:
778 		result = __cvmx_helper_loop_enable(interface);
779 		break;
780 	}
781 	result |= __cvmx_helper_board_hardware_enable(interface);
782 	return result;
783 }
784 
785 /**
786  * Function to adjust internal IPD pointer alignments
787  *
788  * Returns 0 on success
789  *	   !0 on failure
790  */
791 static int __cvmx_helper_errata_fix_ipd_ptr_alignment(void)
792 {
793 #define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \
794      (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_FIRST_MBUFF_SKIP)
795 #define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \
796 	(CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_NOT_FIRST_MBUFF_SKIP)
797 #define FIX_IPD_OUTPORT 0
798 	/* Ports 0-15 are interface 0, 16-31 are interface 1 */
799 #define INTERFACE(port) (port >> 4)
800 #define INDEX(port) (port & 0xf)
801 	uint64_t *p64;
802 	cvmx_pko_command_word0_t pko_command;
803 	union cvmx_buf_ptr g_buffer, pkt_buffer;
804 	cvmx_wqe_t *work;
805 	int size, num_segs = 0, wqe_pcnt, pkt_pcnt;
806 	union cvmx_gmxx_prtx_cfg gmx_cfg;
807 	int retry_cnt;
808 	int retry_loop_cnt;
809 	int i;
810 
811 	/* Save values for restore at end */
812 	uint64_t prtx_cfg =
813 	    cvmx_read_csr(CVMX_GMXX_PRTX_CFG
814 			  (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
815 	uint64_t tx_ptr_en =
816 	    cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
817 	uint64_t rx_ptr_en =
818 	    cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
819 	uint64_t rxx_jabber =
820 	    cvmx_read_csr(CVMX_GMXX_RXX_JABBER
821 			  (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
822 	uint64_t frame_max =
823 	    cvmx_read_csr(CVMX_GMXX_RXX_FRM_MAX
824 			  (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
825 
826 	/* Configure port to gig FDX as required for loopback mode */
827 	cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT);
828 
829 	/*
830 	 * Disable reception on all ports so if traffic is present it
831 	 * will not interfere.
832 	 */
833 	cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 0);
834 
835 	__delay(100000000ull);
836 
837 	for (retry_loop_cnt = 0; retry_loop_cnt < 10; retry_loop_cnt++) {
838 		retry_cnt = 100000;
839 		wqe_pcnt = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
840 		pkt_pcnt = (wqe_pcnt >> 7) & 0x7f;
841 		wqe_pcnt &= 0x7f;
842 
843 		num_segs = (2 + pkt_pcnt - wqe_pcnt) & 3;
844 
845 		if (num_segs == 0)
846 			goto fix_ipd_exit;
847 
848 		num_segs += 1;
849 
850 		size =
851 		    FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES +
852 		    ((num_segs - 1) * FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES) -
853 		    (FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES / 2);
854 
855 		cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)),
856 			       1 << INDEX(FIX_IPD_OUTPORT));
857 		CVMX_SYNC;
858 
859 		g_buffer.u64 = 0;
860 		g_buffer.s.addr =
861 		    cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_WQE_POOL));
862 		if (g_buffer.s.addr == 0) {
863 			cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
864 				     "buffer allocation failure.\n");
865 			goto fix_ipd_exit;
866 		}
867 
868 		g_buffer.s.pool = CVMX_FPA_WQE_POOL;
869 		g_buffer.s.size = num_segs;
870 
871 		pkt_buffer.u64 = 0;
872 		pkt_buffer.s.addr =
873 		    cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL));
874 		if (pkt_buffer.s.addr == 0) {
875 			cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
876 				     "buffer allocation failure.\n");
877 			goto fix_ipd_exit;
878 		}
879 		pkt_buffer.s.i = 1;
880 		pkt_buffer.s.pool = CVMX_FPA_PACKET_POOL;
881 		pkt_buffer.s.size = FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES;
882 
883 		p64 = (uint64_t *) cvmx_phys_to_ptr(pkt_buffer.s.addr);
884 		p64[0] = 0xffffffffffff0000ull;
885 		p64[1] = 0x08004510ull;
886 		p64[2] = ((uint64_t) (size - 14) << 48) | 0x5ae740004000ull;
887 		p64[3] = 0x3a5fc0a81073c0a8ull;
888 
889 		for (i = 0; i < num_segs; i++) {
890 			if (i > 0)
891 				pkt_buffer.s.size =
892 				    FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES;
893 
894 			if (i == (num_segs - 1))
895 				pkt_buffer.s.i = 0;
896 
897 			*(uint64_t *) cvmx_phys_to_ptr(g_buffer.s.addr +
898 						       8 * i) = pkt_buffer.u64;
899 		}
900 
901 		/* Build the PKO command */
902 		pko_command.u64 = 0;
903 		pko_command.s.segs = num_segs;
904 		pko_command.s.total_bytes = size;
905 		pko_command.s.dontfree = 0;
906 		pko_command.s.gather = 1;
907 
908 		gmx_cfg.u64 =
909 		    cvmx_read_csr(CVMX_GMXX_PRTX_CFG
910 				  (INDEX(FIX_IPD_OUTPORT),
911 				   INTERFACE(FIX_IPD_OUTPORT)));
912 		gmx_cfg.s.en = 1;
913 		cvmx_write_csr(CVMX_GMXX_PRTX_CFG
914 			       (INDEX(FIX_IPD_OUTPORT),
915 				INTERFACE(FIX_IPD_OUTPORT)), gmx_cfg.u64);
916 		cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
917 			       1 << INDEX(FIX_IPD_OUTPORT));
918 		cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
919 			       1 << INDEX(FIX_IPD_OUTPORT));
920 
921 		cvmx_write_csr(CVMX_GMXX_RXX_JABBER
922 			       (INDEX(FIX_IPD_OUTPORT),
923 				INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
924 		cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
925 			       (INDEX(FIX_IPD_OUTPORT),
926 				INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
927 
928 		cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT,
929 					     cvmx_pko_get_base_queue
930 					     (FIX_IPD_OUTPORT),
931 					     CVMX_PKO_LOCK_CMD_QUEUE);
932 		cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT,
933 					    cvmx_pko_get_base_queue
934 					    (FIX_IPD_OUTPORT), pko_command,
935 					    g_buffer, CVMX_PKO_LOCK_CMD_QUEUE);
936 
937 		CVMX_SYNC;
938 
939 		do {
940 			work = cvmx_pow_work_request_sync(CVMX_POW_WAIT);
941 			retry_cnt--;
942 		} while ((work == NULL) && (retry_cnt > 0));
943 
944 		if (!retry_cnt)
945 			cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
946 				     "get_work() timeout occurred.\n");
947 
948 		/* Free packet */
949 		if (work)
950 			cvmx_helper_free_packet_data(work);
951 	}
952 
953 fix_ipd_exit:
954 
955 	/* Return CSR configs to saved values */
956 	cvmx_write_csr(CVMX_GMXX_PRTX_CFG
957 		       (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
958 		       prtx_cfg);
959 	cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
960 		       tx_ptr_en);
961 	cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
962 		       rx_ptr_en);
963 	cvmx_write_csr(CVMX_GMXX_RXX_JABBER
964 		       (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
965 		       rxx_jabber);
966 	cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
967 		       (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
968 		       frame_max);
969 	cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0);
970 
971 	CVMX_SYNC;
972 	if (num_segs)
973 		cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n");
974 
975 	return !!num_segs;
976 
977 }
978 
979 /**
980  * Called after all internal packet IO paths are setup. This
981  * function enables IPD/PIP and begins packet input and output.
982  *
983  * Returns Zero on success, negative on failure
984  */
985 int cvmx_helper_ipd_and_packet_input_enable(void)
986 {
987 	int num_interfaces;
988 	int interface;
989 
990 	/* Enable IPD */
991 	cvmx_ipd_enable();
992 
993 	/*
994 	 * Time to enable hardware ports packet input and output. Note
995 	 * that at this point IPD/PIP must be fully functional and PKO
996 	 * must be disabled
997 	 */
998 	num_interfaces = cvmx_helper_get_number_of_interfaces();
999 	for (interface = 0; interface < num_interfaces; interface++) {
1000 		if (cvmx_helper_ports_on_interface(interface) > 0)
1001 			__cvmx_helper_packet_hardware_enable(interface);
1002 	}
1003 
1004 	/* Finally enable PKO now that the entire path is up and running */
1005 	cvmx_pko_enable();
1006 
1007 	if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1)
1008 	     || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1))
1009 	    && (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM))
1010 		__cvmx_helper_errata_fix_ipd_ptr_alignment();
1011 	return 0;
1012 }
1013 EXPORT_SYMBOL_GPL(cvmx_helper_ipd_and_packet_input_enable);
1014 
1015 /**
1016  * Initialize the PIP, IPD, and PKO hardware to support
1017  * simple priority based queues for the ethernet ports. Each
1018  * port is configured with a number of priority queues based
1019  * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
1020  * priority than the previous.
1021  *
1022  * Returns Zero on success, non-zero on failure
1023  */
1024 int cvmx_helper_initialize_packet_io_global(void)
1025 {
1026 	int result = 0;
1027 	int interface;
1028 	union cvmx_l2c_cfg l2c_cfg;
1029 	union cvmx_smix_en smix_en;
1030 	const int num_interfaces = cvmx_helper_get_number_of_interfaces();
1031 
1032 	/*
1033 	 * CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to
1034 	 * be disabled.
1035 	 */
1036 	if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
1037 		__cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
1038 
1039 	/*
1040 	 * Tell L2 to give the IOB statically higher priority compared
1041 	 * to the cores. This avoids conditions where IO blocks might
1042 	 * be starved under very high L2 loads.
1043 	 */
1044 	l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
1045 	l2c_cfg.s.lrf_arb_mode = 0;
1046 	l2c_cfg.s.rfb_arb_mode = 0;
1047 	cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
1048 
1049 	/* Make sure SMI/MDIO is enabled so we can query PHYs */
1050 	smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0));
1051 	if (!smix_en.s.en) {
1052 		smix_en.s.en = 1;
1053 		cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64);
1054 	}
1055 
1056 	/* Newer chips actually have two SMI/MDIO interfaces */
1057 	if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
1058 	    !OCTEON_IS_MODEL(OCTEON_CN58XX) &&
1059 	    !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
1060 		smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1));
1061 		if (!smix_en.s.en) {
1062 			smix_en.s.en = 1;
1063 			cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64);
1064 		}
1065 	}
1066 
1067 	cvmx_pko_initialize_global();
1068 	for (interface = 0; interface < num_interfaces; interface++) {
1069 		result |= cvmx_helper_interface_probe(interface);
1070 		if (cvmx_helper_ports_on_interface(interface) > 0)
1071 			cvmx_dprintf("Interface %d has %d ports (%s)\n",
1072 				     interface,
1073 				     cvmx_helper_ports_on_interface(interface),
1074 				     cvmx_helper_interface_mode_to_string
1075 				     (cvmx_helper_interface_get_mode
1076 				      (interface)));
1077 		result |= __cvmx_helper_interface_setup_ipd(interface);
1078 		result |= __cvmx_helper_interface_setup_pko(interface);
1079 	}
1080 
1081 	result |= __cvmx_helper_global_setup_ipd();
1082 	result |= __cvmx_helper_global_setup_pko();
1083 
1084 	/* Enable any flow control and backpressure */
1085 	result |= __cvmx_helper_global_setup_backpressure();
1086 
1087 #if CVMX_HELPER_ENABLE_IPD
1088 	result |= cvmx_helper_ipd_and_packet_input_enable();
1089 #endif
1090 	return result;
1091 }
1092 EXPORT_SYMBOL_GPL(cvmx_helper_initialize_packet_io_global);
1093 
1094 /**
1095  * Does core local initialization for packet io
1096  *
1097  * Returns Zero on success, non-zero on failure
1098  */
1099 int cvmx_helper_initialize_packet_io_local(void)
1100 {
1101 	return cvmx_pko_initialize_local();
1102 }
1103 
1104 /**
1105  * Return the link state of an IPD/PKO port as returned by
1106  * auto negotiation. The result of this function may not match
1107  * Octeon's link config if auto negotiation has changed since
1108  * the last call to cvmx_helper_link_set().
1109  *
1110  * @ipd_port: IPD/PKO port to query
1111  *
1112  * Returns Link state
1113  */
1114 cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
1115 {
1116 	cvmx_helper_link_info_t result;
1117 	int interface = cvmx_helper_get_interface_num(ipd_port);
1118 	int index = cvmx_helper_get_interface_index_num(ipd_port);
1119 
1120 	/* The default result will be a down link unless the code below
1121 	   changes it */
1122 	result.u64 = 0;
1123 
1124 	if (index >= cvmx_helper_ports_on_interface(interface))
1125 		return result;
1126 
1127 	switch (cvmx_helper_interface_get_mode(interface)) {
1128 	case CVMX_HELPER_INTERFACE_MODE_DISABLED:
1129 	case CVMX_HELPER_INTERFACE_MODE_PCIE:
1130 		/* Network links are not supported */
1131 		break;
1132 	case CVMX_HELPER_INTERFACE_MODE_XAUI:
1133 		result = __cvmx_helper_xaui_link_get(ipd_port);
1134 		break;
1135 	case CVMX_HELPER_INTERFACE_MODE_GMII:
1136 		if (index == 0)
1137 			result = __cvmx_helper_rgmii_link_get(ipd_port);
1138 		else {
1139 			result.s.full_duplex = 1;
1140 			result.s.link_up = 1;
1141 			result.s.speed = 1000;
1142 		}
1143 		break;
1144 	case CVMX_HELPER_INTERFACE_MODE_RGMII:
1145 		result = __cvmx_helper_rgmii_link_get(ipd_port);
1146 		break;
1147 	case CVMX_HELPER_INTERFACE_MODE_SPI:
1148 		result = __cvmx_helper_spi_link_get(ipd_port);
1149 		break;
1150 	case CVMX_HELPER_INTERFACE_MODE_SGMII:
1151 	case CVMX_HELPER_INTERFACE_MODE_PICMG:
1152 		result = __cvmx_helper_sgmii_link_get(ipd_port);
1153 		break;
1154 	case CVMX_HELPER_INTERFACE_MODE_NPI:
1155 	case CVMX_HELPER_INTERFACE_MODE_LOOP:
1156 		/* Network links are not supported */
1157 		break;
1158 	}
1159 	return result;
1160 }
1161 EXPORT_SYMBOL_GPL(cvmx_helper_link_get);
1162 
1163 /**
1164  * Configure an IPD/PKO port for the specified link state. This
1165  * function does not influence auto negotiation at the PHY level.
1166  * The passed link state must always match the link state returned
1167  * by cvmx_helper_link_get().
1168  *
1169  * @ipd_port:  IPD/PKO port to configure
1170  * @link_info: The new link state
1171  *
1172  * Returns Zero on success, negative on failure
1173  */
1174 int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
1175 {
1176 	int result = -1;
1177 	int interface = cvmx_helper_get_interface_num(ipd_port);
1178 	int index = cvmx_helper_get_interface_index_num(ipd_port);
1179 
1180 	if (index >= cvmx_helper_ports_on_interface(interface))
1181 		return -1;
1182 
1183 	switch (cvmx_helper_interface_get_mode(interface)) {
1184 	case CVMX_HELPER_INTERFACE_MODE_DISABLED:
1185 	case CVMX_HELPER_INTERFACE_MODE_PCIE:
1186 		break;
1187 	case CVMX_HELPER_INTERFACE_MODE_XAUI:
1188 		result = __cvmx_helper_xaui_link_set(ipd_port, link_info);
1189 		break;
1190 		/*
1191 		 * RGMII/GMII/MII are all treated about the same. Most
1192 		 * functions refer to these ports as RGMII.
1193 		 */
1194 	case CVMX_HELPER_INTERFACE_MODE_RGMII:
1195 	case CVMX_HELPER_INTERFACE_MODE_GMII:
1196 		result = __cvmx_helper_rgmii_link_set(ipd_port, link_info);
1197 		break;
1198 	case CVMX_HELPER_INTERFACE_MODE_SPI:
1199 		result = __cvmx_helper_spi_link_set(ipd_port, link_info);
1200 		break;
1201 	case CVMX_HELPER_INTERFACE_MODE_SGMII:
1202 	case CVMX_HELPER_INTERFACE_MODE_PICMG:
1203 		result = __cvmx_helper_sgmii_link_set(ipd_port, link_info);
1204 		break;
1205 	case CVMX_HELPER_INTERFACE_MODE_NPI:
1206 	case CVMX_HELPER_INTERFACE_MODE_LOOP:
1207 		break;
1208 	}
1209 	return result;
1210 }
1211 EXPORT_SYMBOL_GPL(cvmx_helper_link_set);
1212