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