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