~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/cavium-octeon/executive/cvmx-helper.c

Version: ~ [ linux-5.4-rc3 ] ~ [ linux-5.3.6 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.79 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.149 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.196 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.196 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.75 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp