Merge tag 'mips_fixes_4.21_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips...
[sfrench/cifs-2.6.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 /* 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);