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