xref: /NextBSD/sys/contrib/octeon-sdk/cvmx-helper-xaui.c (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
1 /***********************license start***************
2  * Copyright (c) 2003-2010  Cavium Inc. (support@cavium.com). All rights
3  * reserved.
4  *
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *   * Redistributions of source code must retain the above copyright
11  *     notice, this list of conditions and the following disclaimer.
12  *
13  *   * Redistributions in binary form must reproduce the above
14  *     copyright notice, this list of conditions and the following
15  *     disclaimer in the documentation and/or other materials provided
16  *     with the distribution.
17 
18  *   * Neither the name of Cavium Inc. nor the names of
19  *     its contributors may be used to endorse or promote products
20  *     derived from this software without specific prior written
21  *     permission.
22 
23  * This Software, including technical data, may be subject to U.S. export  control
24  * laws, including the U.S. Export Administration Act and its  associated
25  * regulations, and may be subject to export or import  regulations in other
26  * countries.
27 
28  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29  * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30  * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31  * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32  * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33  * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34  * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35  * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36  * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37  * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38  ***********************license end**************************************/
39 
40 
41 
42 
43 
44 
45 
46 /**
47  * @file
48  *
49  * Functions for XAUI initialization, configuration,
50  * and monitoring.
51  *
52  * <hr>$Revision: 70030 $<hr>
53  */
54 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
55 #include <asm/octeon/cvmx.h>
56 #include <asm/octeon/cvmx-config.h>
57 #ifdef CVMX_ENABLE_PKO_FUNCTIONS
58 #include <asm/octeon/cvmx-qlm.h>
59 #include <asm/octeon/cvmx-helper.h>
60 #include <asm/octeon/cvmx-helper-cfg.h>
61 #endif
62 #include <asm/octeon/cvmx-gmxx-defs.h>
63 #include <asm/octeon/cvmx-pko-defs.h>
64 #include <asm/octeon/cvmx-pcsx-defs.h>
65 #include <asm/octeon/cvmx-pcsxx-defs.h>
66 #include <asm/octeon/cvmx-ciu-defs.h>
67 #else
68 #if !defined(__FreeBSD__) || !defined(_KERNEL)
69 #include "executive-config.h"
70 #include "cvmx-config.h"
71 
72 #ifdef CVMX_ENABLE_PKO_FUNCTIONS
73 
74 #include "cvmx.h"
75 #include "cvmx-helper.h"
76 #include "cvmx-helper-cfg.h"
77 #include "cvmx-qlm.h"
78 #endif
79 #else
80 #include "cvmx.h"
81 #include "cvmx-helper.h"
82 #include "cvmx-qlm.h"
83 #endif
84 #endif
85 
86 #ifdef CVMX_ENABLE_PKO_FUNCTIONS
87 
__cvmx_helper_xaui_enumerate(int interface)88 int __cvmx_helper_xaui_enumerate(int interface)
89 {
90 	union cvmx_gmxx_hg2_control gmx_hg2_control;
91 
92 	/* If HiGig2 is enabled return 16 ports, otherwise return 1 port */
93 	gmx_hg2_control.u64 = cvmx_read_csr(CVMX_GMXX_HG2_CONTROL(interface));
94 	if (gmx_hg2_control.s.hg2tx_en)
95 		return 16;
96 	else
97 		return 1;
98 }
99 
100 /**
101  * @INTERNAL
102  * Probe a XAUI interface and determine the number of ports
103  * connected to it. The XAUI interface should still be down
104  * after this call.
105  *
106  * @param interface Interface to probe
107  *
108  * @return Number of ports on the interface. Zero to disable.
109  */
__cvmx_helper_xaui_probe(int interface)110 int __cvmx_helper_xaui_probe(int interface)
111 {
112     int i;
113     cvmx_gmxx_inf_mode_t mode;
114 
115     /* CN63XX Pass 1.0 errata G-14395 requires the QLM De-emphasis be programmed */
116     if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_0))
117     {
118         cvmx_ciu_qlm2_t ciu_qlm;
119         ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM2);
120         ciu_qlm.s.txbypass = 1;
121         ciu_qlm.s.txdeemph = 0x5;
122         ciu_qlm.s.txmargin = 0x1a;
123         cvmx_write_csr(CVMX_CIU_QLM2, ciu_qlm.u64);
124     }
125 
126     /* CN63XX Pass 2.0 and 2.1 errata G-15273 requires the QLM De-emphasis be
127         programmed when using a 156.25Mhz ref clock */
128     if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0) ||
129         OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_1))
130     {
131         /* Read the QLM speed pins */
132         cvmx_mio_rst_boot_t mio_rst_boot;
133         mio_rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
134 
135         if (mio_rst_boot.cn63xx.qlm2_spd == 0xb)
136         {
137             cvmx_ciu_qlm2_t ciu_qlm;
138             ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM2);
139             ciu_qlm.s.txbypass = 1;
140             ciu_qlm.s.txdeemph = 0xa;
141             ciu_qlm.s.txmargin = 0x1f;
142             cvmx_write_csr(CVMX_CIU_QLM2, ciu_qlm.u64);
143         }
144     }
145 
146     /* Check if QLM is configured correct for XAUI/RXAUI, verify the
147        speed as well as mode */
148     if (OCTEON_IS_MODEL(OCTEON_CN6XXX))
149     {
150         int qlm, status;
151 
152         qlm = cvmx_qlm_interface(interface);
153         status = cvmx_qlm_get_status(qlm);
154         if (status != 2 && status != 10)
155             return 0;
156     }
157 
158     /* Due to errata GMX-700 on CN56XXp1.x and CN52XXp1.x, the interface
159         needs to be enabled before IPD otherwise per port backpressure
160         may not work properly */
161     mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
162     mode.s.en = 1;
163     cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
164 
165     __cvmx_helper_setup_gmx(interface, 1);
166 
167     if (!OCTEON_IS_MODEL(OCTEON_CN68XX))
168     {
169 	/* Setup PKO to support 16 ports for HiGig2 virtual ports. We're pointing
170 	    all of the PKO packet ports for this interface to the XAUI. This allows
171 	    us to use HiGig2 backpressure per port */
172 	for (i=0; i<16; i++)
173 	{
174 	    cvmx_pko_mem_port_ptrs_t pko_mem_port_ptrs;
175 	    pko_mem_port_ptrs.u64 = 0;
176 	    /* We set each PKO port to have equal priority in a round robin
177 	        fashion */
178 	    pko_mem_port_ptrs.s.static_p = 0;
179 	    pko_mem_port_ptrs.s.qos_mask = 0xff;
180 	    /* All PKO ports map to the same XAUI hardware port */
181 	    pko_mem_port_ptrs.s.eid = interface*4;
182 	    pko_mem_port_ptrs.s.pid = interface*16 + i;
183 	    cvmx_write_csr(CVMX_PKO_MEM_PORT_PTRS, pko_mem_port_ptrs.u64);
184 	}
185     }
186 
187     return __cvmx_helper_xaui_enumerate(interface);
188 }
189 
190 /**
191  * @INTERNAL
192  * Bringup XAUI interface. After this call packet I/O should be
193  * fully functional.
194  *
195  * @param interface Interface to bring up
196  *
197  * @return Zero on success, negative on failure
198  */
__cvmx_helper_xaui_link_init(int interface)199 static int __cvmx_helper_xaui_link_init(int interface)
200 {
201     cvmx_gmxx_prtx_cfg_t          gmx_cfg;
202     cvmx_pcsxx_control1_reg_t     xauiCtl;
203     cvmx_pcsxx_misc_ctl_reg_t     xauiMiscCtl;
204     cvmx_gmxx_tx_xaui_ctl_t       gmxXauiTxCtl;
205 
206     /* (1) Interface has already been enabled. */
207 
208     /* (2) Disable GMX. */
209     xauiMiscCtl.u64 = cvmx_read_csr(CVMX_PCSXX_MISC_CTL_REG(interface));
210     xauiMiscCtl.s.gmxeno = 1;
211     cvmx_write_csr (CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
212 
213     /* (3) Disable GMX and PCSX interrupts. */
214     cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0,interface), 0x0);
215     cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0);
216     cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0);
217 
218     /* (4) Bring up the PCSX and GMX reconciliation layer. */
219     /* (4)a Set polarity and lane swapping. */
220     /* (4)b */
221     gmxXauiTxCtl.u64 = cvmx_read_csr (CVMX_GMXX_TX_XAUI_CTL(interface));
222     gmxXauiTxCtl.s.dic_en = 1; /* Enable better IFG packing and improves performance */
223     gmxXauiTxCtl.s.uni_en = 0;
224     cvmx_write_csr (CVMX_GMXX_TX_XAUI_CTL(interface), gmxXauiTxCtl.u64);
225 
226     /* (4)c Aply reset sequence */
227     xauiCtl.u64 = cvmx_read_csr (CVMX_PCSXX_CONTROL1_REG(interface));
228     xauiCtl.s.lo_pwr = 0;
229 
230     /* Errata G-15618 requires disabling PCS soft reset in some OCTEON II models. */
231     if (!OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)
232         && !OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)
233         && !OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_1)
234         && !OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_X)
235         && !OCTEON_IS_MODEL(OCTEON_CN68XX))
236         xauiCtl.s.reset  = 1;
237     cvmx_write_csr (CVMX_PCSXX_CONTROL1_REG(interface), xauiCtl.u64);
238 
239     /* Wait for PCS to come out of reset */
240     if (CVMX_WAIT_FOR_FIELD64(CVMX_PCSXX_CONTROL1_REG(interface), cvmx_pcsxx_control1_reg_t, reset, ==, 0, 10000))
241         return -1;
242     /* Wait for PCS to be aligned */
243     if (CVMX_WAIT_FOR_FIELD64(CVMX_PCSXX_10GBX_STATUS_REG(interface), cvmx_pcsxx_10gbx_status_reg_t, alignd, ==, 1, 10000))
244         return -1;
245     /* Wait for RX to be ready */
246     if (CVMX_WAIT_FOR_FIELD64(CVMX_GMXX_RX_XAUI_CTL(interface), cvmx_gmxx_rx_xaui_ctl_t, status, ==, 0, 10000))
247         return -1;
248 
249     /* (6) Configure GMX */
250 
251     /* Wait for GMX RX to be idle */
252     if (CVMX_WAIT_FOR_FIELD64(CVMX_GMXX_PRTX_CFG(0, interface), cvmx_gmxx_prtx_cfg_t, rx_idle, ==, 1, 10000))
253         return -1;
254     /* Wait for GMX TX to be idle */
255     if (CVMX_WAIT_FOR_FIELD64(CVMX_GMXX_PRTX_CFG(0, interface), cvmx_gmxx_prtx_cfg_t, tx_idle, ==, 1, 10000))
256         return -1;
257 
258     /* GMX configure */
259     gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
260     gmx_cfg.s.speed = 1;
261     gmx_cfg.s.speed_msb = 0;
262     gmx_cfg.s.slottime = 1;
263     cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), 1);
264     cvmx_write_csr(CVMX_GMXX_TXX_SLOT(0, interface), 512);
265     cvmx_write_csr(CVMX_GMXX_TXX_BURST(0, interface), 8192);
266     cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
267 
268     /* Wait for receive link */
269     if (CVMX_WAIT_FOR_FIELD64(CVMX_PCSXX_STATUS1_REG(interface), cvmx_pcsxx_status1_reg_t, rcv_lnk, ==, 1, 10000))
270         return -1;
271     if (CVMX_WAIT_FOR_FIELD64(CVMX_PCSXX_STATUS2_REG(interface), cvmx_pcsxx_status2_reg_t, xmtflt, ==, 0, 10000))
272         return -1;
273     if (CVMX_WAIT_FOR_FIELD64(CVMX_PCSXX_STATUS2_REG(interface), cvmx_pcsxx_status2_reg_t, rcvflt, ==, 0, 10000))
274         return -1;
275 
276     /* (8) Enable packet reception */
277     xauiMiscCtl.s.gmxeno = 0;
278     cvmx_write_csr (CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
279 
280     /* Clear all error interrupts before enabling the interface. */
281     cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(0,interface), ~0x0ull);
282     cvmx_write_csr(CVMX_GMXX_TX_INT_REG(interface), ~0x0ull);
283     cvmx_write_csr(CVMX_PCSXX_INT_REG(interface), ~0x0ull);
284 
285     /* Enable GMX */
286     gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
287     gmx_cfg.s.en = 1;
288     cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
289 
290     return 0;
291 }
292 
293 /**
294  * @INTERNAL
295  * Bringup and enable a XAUI interface. After this call packet
296  * I/O should be fully functional. This is called with IPD
297  * enabled but PKO disabled.
298  *
299  * @param interface Interface to bring up
300  *
301  * @return Zero on success, negative on failure
302  */
__cvmx_helper_xaui_enable(int interface)303 int __cvmx_helper_xaui_enable(int interface)
304 {
305     /* Setup PKND and BPID */
306     if (octeon_has_feature(OCTEON_FEATURE_PKND))
307     {
308         cvmx_gmxx_bpid_msk_t bpid_msk;
309         cvmx_gmxx_bpid_mapx_t bpid_map;
310         cvmx_gmxx_prtx_cfg_t gmxx_prtx_cfg;
311         cvmx_gmxx_txx_append_t gmxx_txx_append_cfg;
312 
313         /* Setup PKIND */
314         gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
315         gmxx_prtx_cfg.s.pknd = cvmx_helper_get_pknd(interface, 0);
316         cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmxx_prtx_cfg.u64);
317 
318         /* Setup BPID */
319         bpid_map.u64 = cvmx_read_csr(CVMX_GMXX_BPID_MAPX(0, interface));
320         bpid_map.s.val = 1;
321         bpid_map.s.bpid = cvmx_helper_get_bpid(interface, 0);
322         cvmx_write_csr(CVMX_GMXX_BPID_MAPX(0, interface), bpid_map.u64);
323 
324         bpid_msk.u64 = cvmx_read_csr(CVMX_GMXX_BPID_MSK(interface));
325         bpid_msk.s.msk_or |= 1;
326         bpid_msk.s.msk_and &= ~1;
327         cvmx_write_csr(CVMX_GMXX_BPID_MSK(interface), bpid_msk.u64);
328 
329         /* CN68XX adds the padding and FCS in PKO, not GMX */
330         gmxx_txx_append_cfg.u64 = cvmx_read_csr(CVMX_GMXX_TXX_APPEND(0, interface));
331         gmxx_txx_append_cfg.s.fcs = 0;
332         gmxx_txx_append_cfg.s.pad = 0;
333         cvmx_write_csr(CVMX_GMXX_TXX_APPEND(0, interface), gmxx_txx_append_cfg.u64);
334     }
335 
336     __cvmx_helper_xaui_link_init(interface);
337 
338     return 0;
339 }
340 
341 /**
342  * @INTERNAL
343  * Return the link state of an IPD/PKO port as returned by
344  * auto negotiation. The result of this function may not match
345  * Octeon's link config if auto negotiation has changed since
346  * the last call to cvmx_helper_link_set().
347  *
348  * @param ipd_port IPD/PKO port to query
349  *
350  * @return Link state
351  */
__cvmx_helper_xaui_link_get(int ipd_port)352 cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port)
353 {
354     int interface = cvmx_helper_get_interface_num(ipd_port);
355     cvmx_gmxx_tx_xaui_ctl_t gmxx_tx_xaui_ctl;
356     cvmx_gmxx_rx_xaui_ctl_t gmxx_rx_xaui_ctl;
357     cvmx_pcsxx_status1_reg_t pcsxx_status1_reg;
358     cvmx_helper_link_info_t result;
359 
360     gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
361     gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface));
362     pcsxx_status1_reg.u64 = cvmx_read_csr(CVMX_PCSXX_STATUS1_REG(interface));
363     result.u64 = 0;
364 
365     /* Only return a link if both RX and TX are happy */
366     if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0) &&
367         (pcsxx_status1_reg.s.rcv_lnk == 1))
368     {
369         cvmx_pcsxx_misc_ctl_reg_t misc_ctl;
370         result.s.link_up = 1;
371         result.s.full_duplex = 1;
372         if (OCTEON_IS_MODEL(OCTEON_CN68XX))
373         {
374             cvmx_mio_qlmx_cfg_t qlm_cfg;
375             int lanes;
376             int qlm = (interface == 1) ? 0 : interface;
377 
378             qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(qlm));
379             result.s.speed = cvmx_qlm_get_gbaud_mhz(qlm) * 8 / 10;
380             lanes = (qlm_cfg.s.qlm_cfg == 7) ? 2 : 4;
381             result.s.speed *= lanes;
382         }
383         else if (OCTEON_IS_MODEL(OCTEON_CN6XXX))
384         {
385             int qlm = cvmx_qlm_interface(interface);
386             result.s.speed = cvmx_qlm_get_gbaud_mhz(qlm) * 8 / 10;
387             result.s.speed *= 4;
388         }
389         else
390             result.s.speed = 10000;
391         misc_ctl.u64 = cvmx_read_csr(CVMX_PCSXX_MISC_CTL_REG(interface));
392         if (misc_ctl.s.gmxeno)
393             __cvmx_helper_xaui_link_init(interface);
394     }
395     else
396     {
397         /* Disable GMX and PCSX interrupts. */
398         cvmx_write_csr (CVMX_GMXX_RXX_INT_EN(0,interface), 0x0);
399         cvmx_write_csr (CVMX_GMXX_TX_INT_EN(interface), 0x0);
400         cvmx_write_csr (CVMX_PCSXX_INT_EN_REG(interface), 0x0);
401     }
402     return result;
403 }
404 
405 
406 /**
407  * @INTERNAL
408  * Configure an IPD/PKO port for the specified link state. This
409  * function does not influence auto negotiation at the PHY level.
410  * The passed link state must always match the link state returned
411  * by cvmx_helper_link_get(). It is normally best to use
412  * cvmx_helper_link_autoconf() instead.
413  *
414  * @param ipd_port  IPD/PKO port to configure
415  * @param link_info The new link state
416  *
417  * @return Zero on success, negative on failure
418  */
__cvmx_helper_xaui_link_set(int ipd_port,cvmx_helper_link_info_t link_info)419 int __cvmx_helper_xaui_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
420 {
421     int interface = cvmx_helper_get_interface_num(ipd_port);
422     cvmx_gmxx_tx_xaui_ctl_t gmxx_tx_xaui_ctl;
423     cvmx_gmxx_rx_xaui_ctl_t gmxx_rx_xaui_ctl;
424 
425     gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
426     gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface));
427 
428     /* If the link shouldn't be up, then just return */
429     if (!link_info.s.link_up)
430         return 0;
431 
432     /* Do nothing if both RX and TX are happy */
433     if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0))
434         return 0;
435 
436     /* Bring the link up */
437     return __cvmx_helper_xaui_link_init(interface);
438 }
439 
440 
441 /**
442  * @INTERNAL
443  * Configure a port for internal and/or external loopback. Internal loopback
444  * causes packets sent by the port to be received by Octeon. External loopback
445  * causes packets received from the wire to sent out again.
446  *
447  * @param ipd_port IPD/PKO port to loopback.
448  * @param enable_internal
449  *                 Non zero if you want internal loopback
450  * @param enable_external
451  *                 Non zero if you want external loopback
452  *
453  * @return Zero on success, negative on failure.
454  */
__cvmx_helper_xaui_configure_loopback(int ipd_port,int enable_internal,int enable_external)455 extern int __cvmx_helper_xaui_configure_loopback(int ipd_port, int enable_internal, int enable_external)
456 {
457     int interface = cvmx_helper_get_interface_num(ipd_port);
458     cvmx_pcsxx_control1_reg_t pcsxx_control1_reg;
459     cvmx_gmxx_xaui_ext_loopback_t gmxx_xaui_ext_loopback;
460 
461     /* Set the internal loop */
462     pcsxx_control1_reg.u64 = cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
463     pcsxx_control1_reg.s.loopbck1 = enable_internal;
464     cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface), pcsxx_control1_reg.u64);
465 
466     /* Set the external loop */
467     gmxx_xaui_ext_loopback.u64 = cvmx_read_csr(CVMX_GMXX_XAUI_EXT_LOOPBACK(interface));
468     gmxx_xaui_ext_loopback.s.en = enable_external;
469     cvmx_write_csr(CVMX_GMXX_XAUI_EXT_LOOPBACK(interface), gmxx_xaui_ext_loopback.u64);
470 
471     /* Take the link through a reset */
472     return __cvmx_helper_xaui_link_init(interface);
473 }
474 
475 #endif /* CVMX_ENABLE_PKO_FUNCTIONS */
476 
477