1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2020-2022 Marvell International Ltd.
4  *
5  * Helper functions for common, but complicated tasks.
6  */
7 
8 #include <log.h>
9 #include <linux/delay.h>
10 
11 #include <mach/cvmx-regs.h>
12 #include <mach/cvmx-csr.h>
13 #include <mach/cvmx-bootmem.h>
14 #include <mach/octeon-model.h>
15 #include <mach/cvmx-fuse.h>
16 #include <mach/octeon-feature.h>
17 #include <mach/cvmx-qlm.h>
18 #include <mach/octeon_qlm.h>
19 #include <mach/cvmx-pcie.h>
20 #include <mach/cvmx-coremask.h>
21 
22 #include <mach/cvmx-agl-defs.h>
23 #include <mach/cvmx-asxx-defs.h>
24 #include <mach/cvmx-bgxx-defs.h>
25 #include <mach/cvmx-dbg-defs.h>
26 #include <mach/cvmx-gmxx-defs.h>
27 #include <mach/cvmx-gserx-defs.h>
28 #include <mach/cvmx-ipd-defs.h>
29 #include <mach/cvmx-l2c-defs.h>
30 #include <mach/cvmx-npi-defs.h>
31 #include <mach/cvmx-pcsx-defs.h>
32 #include <mach/cvmx-pexp-defs.h>
33 #include <mach/cvmx-pki-defs.h>
34 #include <mach/cvmx-pko-defs.h>
35 #include <mach/cvmx-smix-defs.h>
36 #include <mach/cvmx-sriox-defs.h>
37 #include <mach/cvmx-helper.h>
38 #include <mach/cvmx-helper-board.h>
39 #include <mach/cvmx-helper-fdt.h>
40 #include <mach/cvmx-helper-bgx.h>
41 #include <mach/cvmx-helper-cfg.h>
42 #include <mach/cvmx-helper-ipd.h>
43 #include <mach/cvmx-helper-util.h>
44 #include <mach/cvmx-helper-pki.h>
45 #include <mach/cvmx-helper-pko.h>
46 #include <mach/cvmx-helper-pko3.h>
47 #include <mach/cvmx-global-resources.h>
48 #include <mach/cvmx-pko-internal-ports-range.h>
49 #include <mach/cvmx-pko3-queue.h>
50 #include <mach/cvmx-gmx.h>
51 #include <mach/cvmx-hwpko.h>
52 #include <mach/cvmx-ilk.h>
53 #include <mach/cvmx-ipd.h>
54 #include <mach/cvmx-pip.h>
55 
56 /**
57  * @INTERNAL
58  * This structure specifies the interface methods used by an interface.
59  *
60  * @param mode		Interface mode.
61  *
62  * @param enumerate	Method the get number of interface ports.
63  *
64  * @param probe		Method to probe an interface to get the number of
65  *			connected ports.
66  *
67  * @param enable	Method to enable an interface
68  *
69  * @param link_get	Method to get the state of an interface link.
70  *
71  * @param link_set	Method to configure an interface link to the specified
72  *			state.
73  *
74  * @param loopback	Method to configure a port in loopback.
75  */
76 struct iface_ops {
77 	cvmx_helper_interface_mode_t mode;
78 	int (*enumerate)(int xiface);
79 	int (*probe)(int xiface);
80 	int (*enable)(int xiface);
81 	cvmx_helper_link_info_t (*link_get)(int ipd_port);
82 	int (*link_set)(int ipd_port, cvmx_helper_link_info_t link_info);
83 	int (*loopback)(int ipd_port, int en_in, int en_ex);
84 };
85 
86 /**
87  * @INTERNAL
88  * This structure is used by disabled interfaces.
89  */
90 static const struct iface_ops iface_ops_dis = {
91 	.mode = CVMX_HELPER_INTERFACE_MODE_DISABLED,
92 };
93 
94 /**
95  * @INTERNAL
96  * This structure specifies the interface methods used by interfaces
97  * configured as gmii.
98  */
99 static const struct iface_ops iface_ops_gmii = {
100 	.mode = CVMX_HELPER_INTERFACE_MODE_GMII,
101 	.enumerate = __cvmx_helper_rgmii_probe,
102 	.probe = __cvmx_helper_rgmii_probe,
103 	.enable = __cvmx_helper_rgmii_enable,
104 	.link_get = __cvmx_helper_gmii_link_get,
105 	.link_set = __cvmx_helper_rgmii_link_set,
106 	.loopback = __cvmx_helper_rgmii_configure_loopback,
107 };
108 
109 /**
110  * @INTERNAL
111  * This structure specifies the interface methods used by interfaces
112  * configured as rgmii.
113  */
114 static const struct iface_ops iface_ops_rgmii = {
115 	.mode = CVMX_HELPER_INTERFACE_MODE_RGMII,
116 	.enumerate = __cvmx_helper_rgmii_probe,
117 	.probe = __cvmx_helper_rgmii_probe,
118 	.enable = __cvmx_helper_rgmii_enable,
119 	.link_get = __cvmx_helper_rgmii_link_get,
120 	.link_set = __cvmx_helper_rgmii_link_set,
121 	.loopback = __cvmx_helper_rgmii_configure_loopback,
122 };
123 
124 /**
125  * @INTERNAL
126  * This structure specifies the interface methods used by interfaces
127  * configured as sgmii that use the gmx mac.
128  */
129 static const struct iface_ops iface_ops_sgmii = {
130 	.mode = CVMX_HELPER_INTERFACE_MODE_SGMII,
131 	.enumerate = __cvmx_helper_sgmii_enumerate,
132 	.probe = __cvmx_helper_sgmii_probe,
133 	.enable = __cvmx_helper_sgmii_enable,
134 	.link_get = __cvmx_helper_sgmii_link_get,
135 	.link_set = __cvmx_helper_sgmii_link_set,
136 	.loopback = __cvmx_helper_sgmii_configure_loopback,
137 };
138 
139 /**
140  * @INTERNAL
141  * This structure specifies the interface methods used by interfaces
142  * configured as sgmii that use the bgx mac.
143  */
144 static const struct iface_ops iface_ops_bgx_sgmii = {
145 	.mode = CVMX_HELPER_INTERFACE_MODE_SGMII,
146 	.enumerate = __cvmx_helper_bgx_enumerate,
147 	.probe = __cvmx_helper_bgx_probe,
148 	.enable = __cvmx_helper_bgx_sgmii_enable,
149 	.link_get = __cvmx_helper_bgx_sgmii_link_get,
150 	.link_set = __cvmx_helper_bgx_sgmii_link_set,
151 	.loopback = __cvmx_helper_bgx_sgmii_configure_loopback,
152 };
153 
154 /**
155  * @INTERNAL
156  * This structure specifies the interface methods used by interfaces
157  * configured as qsgmii.
158  */
159 static const struct iface_ops iface_ops_qsgmii = {
160 	.mode = CVMX_HELPER_INTERFACE_MODE_QSGMII,
161 	.enumerate = __cvmx_helper_sgmii_enumerate,
162 	.probe = __cvmx_helper_sgmii_probe,
163 	.enable = __cvmx_helper_sgmii_enable,
164 	.link_get = __cvmx_helper_sgmii_link_get,
165 	.link_set = __cvmx_helper_sgmii_link_set,
166 	.loopback = __cvmx_helper_sgmii_configure_loopback,
167 };
168 
169 /**
170  * @INTERNAL
171  * This structure specifies the interface methods used by interfaces
172  * configured as xaui using the gmx mac.
173  */
174 static const struct iface_ops iface_ops_xaui = {
175 	.mode = CVMX_HELPER_INTERFACE_MODE_XAUI,
176 	.enumerate = __cvmx_helper_xaui_enumerate,
177 	.probe = __cvmx_helper_xaui_probe,
178 	.enable = __cvmx_helper_xaui_enable,
179 	.link_get = __cvmx_helper_xaui_link_get,
180 	.link_set = __cvmx_helper_xaui_link_set,
181 	.loopback = __cvmx_helper_xaui_configure_loopback,
182 };
183 
184 /**
185  * @INTERNAL
186  * This structure specifies the interface methods used by interfaces
187  * configured as xaui using the gmx mac.
188  */
189 static const struct iface_ops iface_ops_bgx_xaui = {
190 	.mode = CVMX_HELPER_INTERFACE_MODE_XAUI,
191 	.enumerate = __cvmx_helper_bgx_enumerate,
192 	.probe = __cvmx_helper_bgx_probe,
193 	.enable = __cvmx_helper_bgx_xaui_enable,
194 	.link_get = __cvmx_helper_bgx_xaui_link_get,
195 	.link_set = __cvmx_helper_bgx_xaui_link_set,
196 	.loopback = __cvmx_helper_bgx_xaui_configure_loopback,
197 };
198 
199 /**
200  * @INTERNAL
201  * This structure specifies the interface methods used by interfaces
202  * configured as rxaui.
203  */
204 static const struct iface_ops iface_ops_rxaui = {
205 	.mode = CVMX_HELPER_INTERFACE_MODE_RXAUI,
206 	.enumerate = __cvmx_helper_xaui_enumerate,
207 	.probe = __cvmx_helper_xaui_probe,
208 	.enable = __cvmx_helper_xaui_enable,
209 	.link_get = __cvmx_helper_xaui_link_get,
210 	.link_set = __cvmx_helper_xaui_link_set,
211 	.loopback = __cvmx_helper_xaui_configure_loopback,
212 };
213 
214 /**
215  * @INTERNAL
216  * This structure specifies the interface methods used by interfaces
217  * configured as xaui using the gmx mac.
218  */
219 static const struct iface_ops iface_ops_bgx_rxaui = {
220 	.mode = CVMX_HELPER_INTERFACE_MODE_RXAUI,
221 	.enumerate = __cvmx_helper_bgx_enumerate,
222 	.probe = __cvmx_helper_bgx_probe,
223 	.enable = __cvmx_helper_bgx_xaui_enable,
224 	.link_get = __cvmx_helper_bgx_xaui_link_get,
225 	.link_set = __cvmx_helper_bgx_xaui_link_set,
226 	.loopback = __cvmx_helper_bgx_xaui_configure_loopback,
227 };
228 
229 /**
230  * @INTERNAL
231  * This structure specifies the interface methods used by interfaces
232  * configured as xlaui.
233  */
234 static const struct iface_ops iface_ops_bgx_xlaui = {
235 	.mode = CVMX_HELPER_INTERFACE_MODE_XLAUI,
236 	.enumerate = __cvmx_helper_bgx_enumerate,
237 	.probe = __cvmx_helper_bgx_probe,
238 	.enable = __cvmx_helper_bgx_xaui_enable,
239 	.link_get = __cvmx_helper_bgx_xaui_link_get,
240 	.link_set = __cvmx_helper_bgx_xaui_link_set,
241 	.loopback = __cvmx_helper_bgx_xaui_configure_loopback,
242 };
243 
244 /**
245  * @INTERNAL
246  * This structure specifies the interface methods used by interfaces
247  * configured as xfi.
248  */
249 static const struct iface_ops iface_ops_bgx_xfi = {
250 	.mode = CVMX_HELPER_INTERFACE_MODE_XFI,
251 	.enumerate = __cvmx_helper_bgx_enumerate,
252 	.probe = __cvmx_helper_bgx_probe,
253 	.enable = __cvmx_helper_bgx_xaui_enable,
254 	.link_get = __cvmx_helper_bgx_xaui_link_get,
255 	.link_set = __cvmx_helper_bgx_xaui_link_set,
256 	.loopback = __cvmx_helper_bgx_xaui_configure_loopback,
257 };
258 
259 static const struct iface_ops iface_ops_bgx_10G_KR = {
260 	.mode = CVMX_HELPER_INTERFACE_MODE_10G_KR,
261 	.enumerate = __cvmx_helper_bgx_enumerate,
262 	.probe = __cvmx_helper_bgx_probe,
263 	.enable = __cvmx_helper_bgx_xaui_enable,
264 	.link_get = __cvmx_helper_bgx_xaui_link_get,
265 	.link_set = __cvmx_helper_bgx_xaui_link_set,
266 	.loopback = __cvmx_helper_bgx_xaui_configure_loopback,
267 };
268 
269 static const struct iface_ops iface_ops_bgx_40G_KR4 = {
270 	.mode = CVMX_HELPER_INTERFACE_MODE_40G_KR4,
271 	.enumerate = __cvmx_helper_bgx_enumerate,
272 	.probe = __cvmx_helper_bgx_probe,
273 	.enable = __cvmx_helper_bgx_xaui_enable,
274 	.link_get = __cvmx_helper_bgx_xaui_link_get,
275 	.link_set = __cvmx_helper_bgx_xaui_link_set,
276 	.loopback = __cvmx_helper_bgx_xaui_configure_loopback,
277 };
278 
279 /**
280  * @INTERNAL
281  * This structure specifies the interface methods used by interfaces
282  * configured as ilk.
283  */
284 static const struct iface_ops iface_ops_ilk = {
285 	.mode = CVMX_HELPER_INTERFACE_MODE_ILK,
286 	.enumerate = __cvmx_helper_ilk_enumerate,
287 	.probe = __cvmx_helper_ilk_probe,
288 	.enable = __cvmx_helper_ilk_enable,
289 	.link_get = __cvmx_helper_ilk_link_get,
290 	.link_set = __cvmx_helper_ilk_link_set,
291 };
292 
293 /**
294  * @INTERNAL
295  * This structure specifies the interface methods used by interfaces
296  * configured as npi.
297  */
298 static const struct iface_ops iface_ops_npi = {
299 	.mode = CVMX_HELPER_INTERFACE_MODE_NPI,
300 	.enumerate = __cvmx_helper_npi_probe,
301 	.probe = __cvmx_helper_npi_probe,
302 	.enable = __cvmx_helper_npi_enable,
303 };
304 
305 /**
306  * @INTERNAL
307  * This structure specifies the interface methods used by interfaces
308  * configured as agl.
309  */
310 static const struct iface_ops iface_ops_agl = {
311 	.mode = CVMX_HELPER_INTERFACE_MODE_AGL,
312 	.enumerate = __cvmx_helper_agl_enumerate,
313 	.probe = __cvmx_helper_agl_probe,
314 	.enable = __cvmx_helper_agl_enable,
315 	.link_get = __cvmx_helper_agl_link_get,
316 	.link_set = __cvmx_helper_agl_link_set,
317 };
318 
319 /**
320  * @INTERNAL
321  * This structure specifies the interface methods used by interfaces
322  * configured as mixed mode, some ports are sgmii and some are xfi.
323  */
324 static const struct iface_ops iface_ops_bgx_mixed = {
325 	.mode = CVMX_HELPER_INTERFACE_MODE_MIXED,
326 	.enumerate = __cvmx_helper_bgx_enumerate,
327 	.probe = __cvmx_helper_bgx_probe,
328 	.enable = __cvmx_helper_bgx_mixed_enable,
329 	.link_get = __cvmx_helper_bgx_mixed_link_get,
330 	.link_set = __cvmx_helper_bgx_mixed_link_set,
331 	.loopback = __cvmx_helper_bgx_mixed_configure_loopback,
332 };
333 
334 /**
335  * @INTERNAL
336  * This structure specifies the interface methods used by interfaces
337  * configured as loop.
338  */
339 static const struct iface_ops iface_ops_loop = {
340 	.mode = CVMX_HELPER_INTERFACE_MODE_LOOP,
341 	.enumerate = __cvmx_helper_loop_enumerate,
342 	.probe = __cvmx_helper_loop_probe,
343 };
344 
345 const struct iface_ops *iface_node_ops[CVMX_MAX_NODES][CVMX_HELPER_MAX_IFACE];
346 #define iface_ops iface_node_ops[0]
347 
348 struct cvmx_iface {
349 	int cvif_ipd_nports;
350 	int cvif_has_fcs; /* PKO fcs for this interface. */
351 	enum cvmx_pko_padding cvif_padding;
352 	cvmx_helper_link_info_t *cvif_ipd_port_link_info;
353 };
354 
355 /*
356  * This has to be static as u-boot expects to probe an interface and
357  * gets the number of its ports.
358  */
359 static struct cvmx_iface cvmx_interfaces[CVMX_MAX_NODES][CVMX_HELPER_MAX_IFACE];
360 
__cvmx_helper_get_num_ipd_ports(int xiface)361 int __cvmx_helper_get_num_ipd_ports(int xiface)
362 {
363 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
364 	struct cvmx_iface *piface;
365 
366 	if (xi.interface >= cvmx_helper_get_number_of_interfaces())
367 		return -1;
368 
369 	piface = &cvmx_interfaces[xi.node][xi.interface];
370 	return piface->cvif_ipd_nports;
371 }
372 
__cvmx_helper_get_pko_padding(int xiface)373 enum cvmx_pko_padding __cvmx_helper_get_pko_padding(int xiface)
374 {
375 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
376 	struct cvmx_iface *piface;
377 
378 	if (xi.interface >= cvmx_helper_get_number_of_interfaces())
379 		return CVMX_PKO_PADDING_NONE;
380 
381 	piface = &cvmx_interfaces[xi.node][xi.interface];
382 	return piface->cvif_padding;
383 }
384 
__cvmx_helper_init_interface(int xiface,int num_ipd_ports,int has_fcs,enum cvmx_pko_padding pad)385 int __cvmx_helper_init_interface(int xiface, int num_ipd_ports, int has_fcs,
386 				 enum cvmx_pko_padding pad)
387 {
388 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
389 	struct cvmx_iface *piface;
390 	cvmx_helper_link_info_t *p;
391 	int i;
392 	int sz;
393 	u64 addr;
394 	char name[32];
395 
396 	if (xi.interface >= cvmx_helper_get_number_of_interfaces())
397 		return -1;
398 
399 	piface = &cvmx_interfaces[xi.node][xi.interface];
400 	piface->cvif_ipd_nports = num_ipd_ports;
401 	piface->cvif_padding = pad;
402 
403 	piface->cvif_has_fcs = has_fcs;
404 
405 	/*
406 	 * allocate the per-ipd_port link_info structure
407 	 */
408 	sz = piface->cvif_ipd_nports * sizeof(cvmx_helper_link_info_t);
409 	snprintf(name, sizeof(name), "__int_%d_link_info", xi.interface);
410 	addr = CAST64(cvmx_bootmem_alloc_named_range_once(sz, 0, 0,
411 							  __alignof(cvmx_helper_link_info_t),
412 							  name, NULL));
413 	piface->cvif_ipd_port_link_info =
414 		(cvmx_helper_link_info_t *)__cvmx_phys_addr_to_ptr(addr, sz);
415 	if (!piface->cvif_ipd_port_link_info) {
416 		if (sz != 0)
417 			debug("iface %d failed to alloc link info\n", xi.interface);
418 		return -1;
419 	}
420 
421 	/* Initialize them */
422 	p = piface->cvif_ipd_port_link_info;
423 
424 	for (i = 0; i < piface->cvif_ipd_nports; i++) {
425 		(*p).u64 = 0;
426 		p++;
427 	}
428 	return 0;
429 }
430 
__cvmx_helper_set_link_info(int xiface,int index,cvmx_helper_link_info_t link_info)431 int __cvmx_helper_set_link_info(int xiface, int index, cvmx_helper_link_info_t link_info)
432 {
433 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
434 	struct cvmx_iface *piface;
435 
436 	if (xi.interface >= cvmx_helper_get_number_of_interfaces())
437 		return -1;
438 
439 	piface = &cvmx_interfaces[xi.node][xi.interface];
440 
441 	if (piface->cvif_ipd_port_link_info) {
442 		piface->cvif_ipd_port_link_info[index] = link_info;
443 		return 0;
444 	}
445 
446 	return -1;
447 }
448 
__cvmx_helper_get_link_info(int xiface,int port)449 cvmx_helper_link_info_t __cvmx_helper_get_link_info(int xiface, int port)
450 {
451 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
452 	struct cvmx_iface *piface;
453 	cvmx_helper_link_info_t err;
454 
455 	err.u64 = 0;
456 
457 	if (xi.interface >= cvmx_helper_get_number_of_interfaces())
458 		return err;
459 	piface = &cvmx_interfaces[xi.node][xi.interface];
460 
461 	if (piface->cvif_ipd_port_link_info)
462 		return piface->cvif_ipd_port_link_info[port];
463 
464 	return err;
465 }
466 
467 /**
468  * Returns if FCS is enabled for the specified interface and port
469  *
470  * @param xiface - interface to check
471  *
472  * Return: zero if FCS is not used, otherwise FCS is used.
473  */
__cvmx_helper_get_has_fcs(int xiface)474 int __cvmx_helper_get_has_fcs(int xiface)
475 {
476 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
477 	return cvmx_interfaces[xi.node][xi.interface].cvif_has_fcs;
478 }
479 
480 u64 cvmx_rgmii_backpressure_dis = 1;
481 
482 typedef int (*cvmx_export_config_t)(void);
483 cvmx_export_config_t cvmx_export_app_config;
484 
485 /*
486  * internal functions that are not exported in the .h file but must be
487  * declared to make gcc happy.
488  */
489 extern cvmx_helper_link_info_t __cvmx_helper_get_link_info(int interface, int port);
490 
491 /**
492  * cvmx_override_ipd_port_setup(int ipd_port) is a function
493  * pointer. It is meant to allow customization of the IPD
494  * port/port kind setup before packet input/output comes online.
495  * It is called after cvmx-helper does the default IPD configuration,
496  * but before IPD is enabled. Users should set this pointer to a
497  * function before calling any cvmx-helper operations.
498  */
499 void (*cvmx_override_ipd_port_setup)(int ipd_port) = NULL;
500 
501 /**
502  * Return the number of interfaces the chip has. Each interface
503  * may have multiple ports. Most chips support two interfaces,
504  * but the CNX0XX and CNX1XX are exceptions. These only support
505  * one interface.
506  *
507  * Return: Number of interfaces on chip
508  */
cvmx_helper_get_number_of_interfaces(void)509 int cvmx_helper_get_number_of_interfaces(void)
510 {
511 	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
512 		return 9;
513 	else if (OCTEON_IS_MODEL(OCTEON_CN66XX))
514 		if (OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_0))
515 			return 7;
516 		else
517 			return 8;
518 	else if (OCTEON_IS_MODEL(OCTEON_CN63XX))
519 		return 6;
520 	else if (OCTEON_IS_MODEL(OCTEON_CN61XX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
521 		return 4;
522 	else if (OCTEON_IS_MODEL(OCTEON_CN70XX))
523 		return 5;
524 	else if (OCTEON_IS_MODEL(OCTEON_CN78XX))
525 		return 10;
526 	else if (OCTEON_IS_MODEL(OCTEON_CNF75XX))
527 		return 5;
528 	else if (OCTEON_IS_MODEL(OCTEON_CN73XX))
529 		return 5;
530 	else
531 		return 3;
532 }
533 
__cvmx_helper_early_ports_on_interface(int interface)534 int __cvmx_helper_early_ports_on_interface(int interface)
535 {
536 	int ports;
537 
538 	if (octeon_has_feature(OCTEON_FEATURE_PKND))
539 		return cvmx_helper_interface_enumerate(interface);
540 
541 	ports = cvmx_helper_interface_enumerate(interface);
542 	ports = __cvmx_helper_board_interface_probe(interface, ports);
543 
544 	return ports;
545 }
546 
547 /**
548  * Return the number of ports on an interface. Depending on the
549  * chip and configuration, this can be 1-16. A value of 0
550  * specifies that the interface doesn't exist or isn't usable.
551  *
552  * @param xiface to get the port count for
553  *
554  * Return: Number of ports on interface. Can be Zero.
555  */
cvmx_helper_ports_on_interface(int xiface)556 int cvmx_helper_ports_on_interface(int xiface)
557 {
558 	if (octeon_has_feature(OCTEON_FEATURE_PKND))
559 		return cvmx_helper_interface_enumerate(xiface);
560 	else
561 		return __cvmx_helper_get_num_ipd_ports(xiface);
562 }
563 
564 /**
565  * @INTERNAL
566  * Return interface mode for CN70XX.
567  */
__cvmx_get_mode_cn70xx(int interface)568 static cvmx_helper_interface_mode_t __cvmx_get_mode_cn70xx(int interface)
569 {
570 	/* SGMII/RXAUI/QSGMII */
571 	if (interface < 2) {
572 		enum cvmx_qlm_mode qlm_mode =
573 			cvmx_qlm_get_dlm_mode(0, interface);
574 
575 		if (qlm_mode == CVMX_QLM_MODE_SGMII)
576 			iface_ops[interface] = &iface_ops_sgmii;
577 		else if (qlm_mode == CVMX_QLM_MODE_QSGMII)
578 			iface_ops[interface] = &iface_ops_qsgmii;
579 		else if (qlm_mode == CVMX_QLM_MODE_RXAUI)
580 			iface_ops[interface] = &iface_ops_rxaui;
581 		else
582 			iface_ops[interface] = &iface_ops_dis;
583 	} else if (interface == 2) { /* DPI */
584 		iface_ops[interface] = &iface_ops_npi;
585 	} else if (interface == 3) { /* LOOP */
586 		iface_ops[interface] = &iface_ops_loop;
587 	} else if (interface == 4) { /* RGMII (AGL) */
588 		cvmx_agl_prtx_ctl_t prtx_ctl;
589 
590 		prtx_ctl.u64 = csr_rd(CVMX_AGL_PRTX_CTL(0));
591 		if (prtx_ctl.s.mode == 0)
592 			iface_ops[interface] = &iface_ops_agl;
593 		else
594 			iface_ops[interface] = &iface_ops_dis;
595 	} else {
596 		iface_ops[interface] = &iface_ops_dis;
597 	}
598 
599 	return iface_ops[interface]->mode;
600 }
601 
602 /**
603  * @INTERNAL
604  * Return interface mode for CN78XX.
605  */
__cvmx_get_mode_cn78xx(int xiface)606 static cvmx_helper_interface_mode_t __cvmx_get_mode_cn78xx(int xiface)
607 {
608 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
609 	/* SGMII/RXAUI/XAUI */
610 	if (xi.interface < 6) {
611 		int qlm = cvmx_qlm_lmac(xiface, 0);
612 		enum cvmx_qlm_mode qlm_mode;
613 
614 		if (qlm == -1) {
615 			iface_node_ops[xi.node][xi.interface] = &iface_ops_dis;
616 			return iface_node_ops[xi.node][xi.interface]->mode;
617 		}
618 		qlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, qlm);
619 
620 		if (qlm_mode == CVMX_QLM_MODE_SGMII)
621 			iface_node_ops[xi.node][xi.interface] = &iface_ops_bgx_sgmii;
622 		else if (qlm_mode == CVMX_QLM_MODE_XAUI)
623 			iface_node_ops[xi.node][xi.interface] = &iface_ops_bgx_xaui;
624 		else if (qlm_mode == CVMX_QLM_MODE_XLAUI)
625 			iface_node_ops[xi.node][xi.interface] = &iface_ops_bgx_xlaui;
626 		else if (qlm_mode == CVMX_QLM_MODE_XFI)
627 			iface_node_ops[xi.node][xi.interface] = &iface_ops_bgx_xfi;
628 		else if (qlm_mode == CVMX_QLM_MODE_RXAUI)
629 			iface_node_ops[xi.node][xi.interface] = &iface_ops_bgx_rxaui;
630 		else
631 			iface_node_ops[xi.node][xi.interface] = &iface_ops_dis;
632 	} else if (xi.interface < 8) {
633 		enum cvmx_qlm_mode qlm_mode;
634 		int found = 0;
635 		int i;
636 		int intf, lane_mask;
637 
638 		if (xi.interface == 6) {
639 			intf = 6;
640 			lane_mask = cvmx_ilk_lane_mask[xi.node][0];
641 		} else {
642 			intf = 7;
643 			lane_mask = cvmx_ilk_lane_mask[xi.node][1];
644 		}
645 		switch (lane_mask) {
646 		default:
647 		case 0x0:
648 			iface_node_ops[xi.node][intf] = &iface_ops_dis;
649 			break;
650 		case 0xf:
651 			qlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, 4);
652 			if (qlm_mode == CVMX_QLM_MODE_ILK)
653 				iface_node_ops[xi.node][intf] = &iface_ops_ilk;
654 			else
655 				iface_node_ops[xi.node][intf] = &iface_ops_dis;
656 			break;
657 		case 0xff:
658 			found = 0;
659 			for (i = 4; i < 6; i++) {
660 				qlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, i);
661 				if (qlm_mode == CVMX_QLM_MODE_ILK)
662 					found++;
663 			}
664 			if (found == 2)
665 				iface_node_ops[xi.node][intf] = &iface_ops_ilk;
666 			else
667 				iface_node_ops[xi.node][intf] = &iface_ops_dis;
668 			break;
669 		case 0xfff:
670 			found = 0;
671 			for (i = 4; i < 7; i++) {
672 				qlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, i);
673 				if (qlm_mode == CVMX_QLM_MODE_ILK)
674 					found++;
675 			}
676 			if (found == 3)
677 				iface_node_ops[xi.node][intf] = &iface_ops_ilk;
678 			else
679 				iface_node_ops[xi.node][intf] = &iface_ops_dis;
680 			break;
681 		case 0xff00:
682 			found = 0;
683 			for (i = 6; i < 8; i++) {
684 				qlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, i);
685 				if (qlm_mode == CVMX_QLM_MODE_ILK)
686 					found++;
687 			}
688 			if (found == 2)
689 				iface_node_ops[xi.node][intf] = &iface_ops_ilk;
690 			else
691 				iface_node_ops[xi.node][intf] = &iface_ops_dis;
692 			break;
693 		case 0xf0:
694 			qlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, 5);
695 			if (qlm_mode == CVMX_QLM_MODE_ILK)
696 				iface_node_ops[xi.node][intf] = &iface_ops_ilk;
697 			else
698 				iface_node_ops[xi.node][intf] = &iface_ops_dis;
699 			break;
700 		case 0xf00:
701 			qlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, 6);
702 			if (qlm_mode == CVMX_QLM_MODE_ILK)
703 				iface_node_ops[xi.node][intf] = &iface_ops_ilk;
704 			else
705 				iface_node_ops[xi.node][intf] = &iface_ops_dis;
706 			break;
707 		case 0xf000:
708 			qlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, 7);
709 			if (qlm_mode == CVMX_QLM_MODE_ILK)
710 				iface_node_ops[xi.node][intf] = &iface_ops_ilk;
711 			else
712 				iface_node_ops[xi.node][intf] = &iface_ops_dis;
713 			break;
714 		case 0xfff0:
715 			found = 0;
716 			for (i = 5; i < 8; i++) {
717 				qlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, i);
718 				if (qlm_mode == CVMX_QLM_MODE_ILK)
719 					found++;
720 			}
721 			if (found == 3)
722 				iface_node_ops[xi.node][intf] = &iface_ops_ilk;
723 			else
724 				iface_node_ops[xi.node][intf] = &iface_ops_dis;
725 			break;
726 		}
727 	} else if (xi.interface == 8) { /* DPI */
728 		int qlm = 0;
729 
730 		for (qlm = 0; qlm < 5; qlm++) {
731 			/* if GSERX_CFG[pcie] == 1, then enable npi */
732 			if (csr_rd_node(xi.node, CVMX_GSERX_CFG(qlm)) & 0x1) {
733 				iface_node_ops[xi.node][xi.interface] =
734 					&iface_ops_npi;
735 				return iface_node_ops[xi.node][xi.interface]->mode;
736 			}
737 		}
738 		iface_node_ops[xi.node][xi.interface] = &iface_ops_dis;
739 	} else if (xi.interface == 9) { /* LOOP */
740 		iface_node_ops[xi.node][xi.interface] = &iface_ops_loop;
741 	} else {
742 		iface_node_ops[xi.node][xi.interface] = &iface_ops_dis;
743 	}
744 
745 	return iface_node_ops[xi.node][xi.interface]->mode;
746 }
747 
748 /**
749  * @INTERNAL
750  * Return interface mode for CN73XX.
751  */
__cvmx_get_mode_cn73xx(int xiface)752 static cvmx_helper_interface_mode_t __cvmx_get_mode_cn73xx(int xiface)
753 {
754 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
755 	int interface = xi.interface;
756 
757 	/* SGMII/XAUI/XLAUI/XFI */
758 	if (interface < 3) {
759 		int qlm = cvmx_qlm_lmac(xiface, 0);
760 		enum cvmx_qlm_mode qlm_mode;
761 
762 		if (qlm == -1) {
763 			iface_ops[interface] = &iface_ops_dis;
764 			return iface_ops[interface]->mode;
765 		}
766 		qlm_mode = cvmx_qlm_get_mode(qlm);
767 
768 		switch (qlm_mode) {
769 		case CVMX_QLM_MODE_SGMII:
770 		case CVMX_QLM_MODE_SGMII_2X1:
771 		case CVMX_QLM_MODE_RGMII_SGMII:
772 		case CVMX_QLM_MODE_RGMII_SGMII_1X1:
773 			iface_ops[interface] = &iface_ops_bgx_sgmii;
774 			break;
775 		case CVMX_QLM_MODE_XAUI:
776 		case CVMX_QLM_MODE_RGMII_XAUI:
777 			iface_ops[interface] = &iface_ops_bgx_xaui;
778 			break;
779 		case CVMX_QLM_MODE_RXAUI:
780 		case CVMX_QLM_MODE_RXAUI_1X2:
781 		case CVMX_QLM_MODE_RGMII_RXAUI:
782 			iface_ops[interface] = &iface_ops_bgx_rxaui;
783 			break;
784 		case CVMX_QLM_MODE_XLAUI:
785 		case CVMX_QLM_MODE_RGMII_XLAUI:
786 			iface_ops[interface] = &iface_ops_bgx_xlaui;
787 			break;
788 		case CVMX_QLM_MODE_XFI:
789 		case CVMX_QLM_MODE_XFI_1X2:
790 		case CVMX_QLM_MODE_RGMII_XFI:
791 			iface_ops[interface] = &iface_ops_bgx_xfi;
792 			break;
793 		case CVMX_QLM_MODE_10G_KR:
794 		case CVMX_QLM_MODE_10G_KR_1X2:
795 		case CVMX_QLM_MODE_RGMII_10G_KR:
796 			iface_ops[interface] = &iface_ops_bgx_10G_KR;
797 			break;
798 		case CVMX_QLM_MODE_40G_KR4:
799 		case CVMX_QLM_MODE_RGMII_40G_KR4:
800 			iface_ops[interface] = &iface_ops_bgx_40G_KR4;
801 			break;
802 		case CVMX_QLM_MODE_MIXED:
803 			iface_ops[interface] = &iface_ops_bgx_mixed;
804 			break;
805 		default:
806 			iface_ops[interface] = &iface_ops_dis;
807 			break;
808 		}
809 	} else if (interface == 3) { /* DPI */
810 		iface_ops[interface] = &iface_ops_npi;
811 	} else if (interface == 4) { /* LOOP */
812 		iface_ops[interface] = &iface_ops_loop;
813 	} else {
814 		iface_ops[interface] = &iface_ops_dis;
815 	}
816 
817 	return iface_ops[interface]->mode;
818 }
819 
820 /**
821  * @INTERNAL
822  * Return interface mode for CNF75XX.
823  *
824  * CNF75XX has a single BGX block, which is attached to two DLMs,
825  * the first, GSER4 only supports SGMII mode, while the second,
826  * GSER5 supports 1G/10G single late modes, i.e. SGMII, XFI, 10G-KR.
827  * Each half-BGX is thus designated as a separate interface with two ports each.
828  */
__cvmx_get_mode_cnf75xx(int xiface)829 static cvmx_helper_interface_mode_t __cvmx_get_mode_cnf75xx(int xiface)
830 {
831 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
832 	int interface = xi.interface;
833 
834 	/* BGX0: SGMII (DLM4/DLM5)/XFI(DLM5)  */
835 	if (interface < 1) {
836 		enum cvmx_qlm_mode qlm_mode;
837 		int qlm = cvmx_qlm_lmac(xiface, 0);
838 
839 		if (qlm == -1) {
840 			iface_ops[interface] = &iface_ops_dis;
841 			return iface_ops[interface]->mode;
842 		}
843 		qlm_mode = cvmx_qlm_get_mode(qlm);
844 
845 		switch (qlm_mode) {
846 		case CVMX_QLM_MODE_SGMII:
847 		case CVMX_QLM_MODE_SGMII_2X1:
848 			iface_ops[interface] = &iface_ops_bgx_sgmii;
849 			break;
850 		case CVMX_QLM_MODE_XFI_1X2:
851 			iface_ops[interface] = &iface_ops_bgx_xfi;
852 			break;
853 		case CVMX_QLM_MODE_10G_KR_1X2:
854 			iface_ops[interface] = &iface_ops_bgx_10G_KR;
855 			break;
856 		case CVMX_QLM_MODE_MIXED:
857 			iface_ops[interface] = &iface_ops_bgx_mixed;
858 			break;
859 		default:
860 			iface_ops[interface] = &iface_ops_dis;
861 			break;
862 		}
863 	} else if ((interface < 3) && OCTEON_IS_MODEL(OCTEON_CNF75XX)) {
864 		/* SRIO is disabled for now */
865 		printf("SRIO disabled for now!\n");
866 		iface_ops[interface] = &iface_ops_dis;
867 	} else if (interface == 3) { /* DPI */
868 		iface_ops[interface] = &iface_ops_npi;
869 	} else if (interface == 4) { /* LOOP */
870 		iface_ops[interface] = &iface_ops_loop;
871 	} else {
872 		iface_ops[interface] = &iface_ops_dis;
873 	}
874 
875 	return iface_ops[interface]->mode;
876 }
877 
878 /**
879  * @INTERNAL
880  * Return interface mode for CN68xx.
881  */
__cvmx_get_mode_cn68xx(int interface)882 static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface)
883 {
884 	union cvmx_mio_qlmx_cfg qlm_cfg;
885 
886 	switch (interface) {
887 	case 0:
888 		qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(0));
889 		/* QLM is disabled when QLM SPD is 15. */
890 		if (qlm_cfg.s.qlm_spd == 15)
891 			iface_ops[interface] = &iface_ops_dis;
892 		else if (qlm_cfg.s.qlm_cfg == 7)
893 			iface_ops[interface] = &iface_ops_rxaui;
894 		else if (qlm_cfg.s.qlm_cfg == 2)
895 			iface_ops[interface] = &iface_ops_sgmii;
896 		else if (qlm_cfg.s.qlm_cfg == 3)
897 			iface_ops[interface] = &iface_ops_xaui;
898 		else
899 			iface_ops[interface] = &iface_ops_dis;
900 		break;
901 
902 	case 1:
903 		qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(0));
904 		/* QLM is disabled when QLM SPD is 15. */
905 		if (qlm_cfg.s.qlm_spd == 15)
906 			iface_ops[interface] = &iface_ops_dis;
907 		else if (qlm_cfg.s.qlm_cfg == 7)
908 			iface_ops[interface] = &iface_ops_rxaui;
909 		else
910 			iface_ops[interface] = &iface_ops_dis;
911 		break;
912 
913 	case 2:
914 	case 3:
915 	case 4:
916 		qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(interface));
917 		/* QLM is disabled when QLM SPD is 15. */
918 		if (qlm_cfg.s.qlm_spd == 15)
919 			iface_ops[interface] = &iface_ops_dis;
920 		else if (qlm_cfg.s.qlm_cfg == 2)
921 			iface_ops[interface] = &iface_ops_sgmii;
922 		else if (qlm_cfg.s.qlm_cfg == 3)
923 			iface_ops[interface] = &iface_ops_xaui;
924 		else
925 			iface_ops[interface] = &iface_ops_dis;
926 		break;
927 
928 	case 5:
929 	case 6:
930 		qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(interface - 4));
931 		/* QLM is disabled when QLM SPD is 15. */
932 		if (qlm_cfg.s.qlm_spd == 15)
933 			iface_ops[interface] = &iface_ops_dis;
934 		else if (qlm_cfg.s.qlm_cfg == 1)
935 			iface_ops[interface] = &iface_ops_ilk;
936 		else
937 			iface_ops[interface] = &iface_ops_dis;
938 		break;
939 
940 	case 7: {
941 		union cvmx_mio_qlmx_cfg qlm_cfg1;
942 		/* Check if PCIe0/PCIe1 is configured for PCIe */
943 		qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(3));
944 		qlm_cfg1.u64 = csr_rd(CVMX_MIO_QLMX_CFG(1));
945 		/* QLM is disabled when QLM SPD is 15. */
946 		if ((qlm_cfg.s.qlm_spd != 15 && qlm_cfg.s.qlm_cfg == 0) ||
947 		    (qlm_cfg1.s.qlm_spd != 15 && qlm_cfg1.s.qlm_cfg == 0))
948 			iface_ops[interface] = &iface_ops_npi;
949 		else
950 			iface_ops[interface] = &iface_ops_dis;
951 	} break;
952 
953 	case 8:
954 		iface_ops[interface] = &iface_ops_loop;
955 		break;
956 
957 	default:
958 		iface_ops[interface] = &iface_ops_dis;
959 		break;
960 	}
961 
962 	return iface_ops[interface]->mode;
963 }
964 
965 /**
966  * @INTERNAL
967  * Return interface mode for an Octeon II
968  */
__cvmx_get_mode_octeon2(int interface)969 static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)
970 {
971 	union cvmx_gmxx_inf_mode mode;
972 
973 	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
974 		return __cvmx_get_mode_cn68xx(interface);
975 
976 	if (interface == 2) {
977 		iface_ops[interface] = &iface_ops_npi;
978 	} else if (interface == 3) {
979 		iface_ops[interface] = &iface_ops_loop;
980 	} else if ((OCTEON_IS_MODEL(OCTEON_CN63XX) &&
981 		    (interface == 4 || interface == 5)) ||
982 		   (OCTEON_IS_MODEL(OCTEON_CN66XX) && interface >= 4 &&
983 		    interface <= 7)) {
984 		/* Only present in CN63XX & CN66XX Octeon model */
985 
986 		/* cn66xx pass1.0 has only 2 SRIO interfaces. */
987 		if ((interface == 5 || interface == 7) &&
988 		    OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_0)) {
989 			iface_ops[interface] = &iface_ops_dis;
990 		} else if (interface == 5 && OCTEON_IS_MODEL(OCTEON_CN66XX)) {
991 			/*
992 			 * Later passes of cn66xx support SRIO0 - x4/x2/x1,
993 			 * SRIO2 - x2/x1, SRIO3 - x1
994 			 */
995 			iface_ops[interface] = &iface_ops_dis;
996 		} else {
997 			/* SRIO is disabled for now */
998 			printf("SRIO disabled for now!\n");
999 			iface_ops[interface] = &iface_ops_dis;
1000 		}
1001 	} else if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
1002 		union cvmx_mio_qlmx_cfg mio_qlm_cfg;
1003 
1004 		/* QLM2 is SGMII0 and QLM1 is SGMII1 */
1005 		if (interface == 0) {
1006 			mio_qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(2));
1007 		} else if (interface == 1) {
1008 			mio_qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(1));
1009 		} else {
1010 			iface_ops[interface] = &iface_ops_dis;
1011 			return iface_ops[interface]->mode;
1012 		}
1013 
1014 		if (mio_qlm_cfg.s.qlm_spd == 15)
1015 			iface_ops[interface] = &iface_ops_dis;
1016 		else if (mio_qlm_cfg.s.qlm_cfg == 9)
1017 			iface_ops[interface] = &iface_ops_sgmii;
1018 		else if (mio_qlm_cfg.s.qlm_cfg == 11)
1019 			iface_ops[interface] = &iface_ops_xaui;
1020 		else
1021 			iface_ops[interface] = &iface_ops_dis;
1022 	} else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) {
1023 		union cvmx_mio_qlmx_cfg qlm_cfg;
1024 
1025 		if (interface == 0) {
1026 			qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(2));
1027 		} else if (interface == 1) {
1028 			qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(0));
1029 		} else {
1030 			iface_ops[interface] = &iface_ops_dis;
1031 			return iface_ops[interface]->mode;
1032 		}
1033 
1034 		if (qlm_cfg.s.qlm_spd == 15)
1035 			iface_ops[interface] = &iface_ops_dis;
1036 		else if (qlm_cfg.s.qlm_cfg == 2)
1037 			iface_ops[interface] = &iface_ops_sgmii;
1038 		else if (qlm_cfg.s.qlm_cfg == 3)
1039 			iface_ops[interface] = &iface_ops_xaui;
1040 		else
1041 			iface_ops[interface] = &iface_ops_dis;
1042 	} else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) {
1043 		if (interface == 0) {
1044 			union cvmx_mio_qlmx_cfg qlm_cfg;
1045 
1046 			qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(0));
1047 			if (qlm_cfg.s.qlm_cfg == 2)
1048 				iface_ops[interface] = &iface_ops_sgmii;
1049 			else
1050 				iface_ops[interface] = &iface_ops_dis;
1051 		} else {
1052 			iface_ops[interface] = &iface_ops_dis;
1053 		}
1054 	} else if (interface == 1 && OCTEON_IS_MODEL(OCTEON_CN63XX)) {
1055 		iface_ops[interface] = &iface_ops_dis;
1056 	} else {
1057 		mode.u64 = csr_rd(CVMX_GMXX_INF_MODE(interface));
1058 
1059 		if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
1060 			switch (mode.cn63xx.mode) {
1061 			case 0:
1062 				iface_ops[interface] = &iface_ops_sgmii;
1063 				break;
1064 
1065 			case 1:
1066 				iface_ops[interface] = &iface_ops_xaui;
1067 				break;
1068 
1069 			default:
1070 				iface_ops[interface] = &iface_ops_dis;
1071 				break;
1072 			}
1073 		} else {
1074 			if (!mode.s.en)
1075 				iface_ops[interface] = &iface_ops_dis;
1076 			else if (mode.s.type)
1077 				iface_ops[interface] = &iface_ops_gmii;
1078 			else
1079 				iface_ops[interface] = &iface_ops_rgmii;
1080 		}
1081 	}
1082 
1083 	return iface_ops[interface]->mode;
1084 }
1085 
1086 /**
1087  * Get the operating mode of an interface. Depending on the Octeon
1088  * chip and configuration, this function returns an enumeration
1089  * of the type of packet I/O supported by an interface.
1090  *
1091  * @param xiface Interface to probe
1092  *
1093  * Return: Mode of the interface. Unknown or unsupported interfaces return
1094  *         DISABLED.
1095  */
cvmx_helper_interface_get_mode(int xiface)1096 cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int xiface)
1097 {
1098 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
1099 
1100 	if (xi.interface < 0 ||
1101 	    xi.interface >= cvmx_helper_get_number_of_interfaces())
1102 		return CVMX_HELPER_INTERFACE_MODE_DISABLED;
1103 
1104 	/*
1105 	 * Check if the interface mode has been already cached. If it has,
1106 	 * simply return it. Otherwise, fall through the rest of the code to
1107 	 * determine the interface mode and cache it in iface_ops.
1108 	 */
1109 	if (iface_node_ops[xi.node][xi.interface]) {
1110 		cvmx_helper_interface_mode_t mode;
1111 
1112 		mode = iface_node_ops[xi.node][xi.interface]->mode;
1113 		return mode;
1114 	}
1115 
1116 	/*
1117 	 * OCTEON III models
1118 	 */
1119 	if (OCTEON_IS_MODEL(OCTEON_CN70XX))
1120 		return __cvmx_get_mode_cn70xx(xi.interface);
1121 
1122 	if (OCTEON_IS_MODEL(OCTEON_CN78XX))
1123 		return __cvmx_get_mode_cn78xx(xiface);
1124 
1125 	if (OCTEON_IS_MODEL(OCTEON_CNF75XX)) {
1126 		cvmx_helper_interface_mode_t mode;
1127 
1128 		mode = __cvmx_get_mode_cnf75xx(xiface);
1129 		return mode;
1130 	}
1131 
1132 	if (OCTEON_IS_MODEL(OCTEON_CN73XX)) {
1133 		cvmx_helper_interface_mode_t mode;
1134 
1135 		mode = __cvmx_get_mode_cn73xx(xiface);
1136 		return mode;
1137 	}
1138 
1139 	/*
1140 	 * Octeon II models
1141 	 */
1142 	if (OCTEON_IS_OCTEON2())
1143 		return __cvmx_get_mode_octeon2(xi.interface);
1144 
1145 	/*
1146 	 * Octeon and Octeon Plus models
1147 	 */
1148 	if (xi.interface == 2) {
1149 		iface_ops[xi.interface] = &iface_ops_npi;
1150 	} else if (xi.interface == 3) {
1151 		iface_ops[xi.interface] = &iface_ops_dis;
1152 	} else {
1153 		union cvmx_gmxx_inf_mode mode;
1154 
1155 		mode.u64 = csr_rd(CVMX_GMXX_INF_MODE(xi.interface));
1156 
1157 		if (!mode.s.en)
1158 			iface_ops[xi.interface] = &iface_ops_dis;
1159 		else if (mode.s.type)
1160 			iface_ops[xi.interface] = &iface_ops_gmii;
1161 		else
1162 			iface_ops[xi.interface] = &iface_ops_rgmii;
1163 	}
1164 
1165 	return iface_ops[xi.interface]->mode;
1166 }
1167 
1168 /**
1169  * Determine the actual number of hardware ports connected to an
1170  * interface. It doesn't setup the ports or enable them.
1171  *
1172  * @param xiface Interface to enumerate
1173  *
1174  * Return: The number of ports on the interface, negative on failure
1175  */
cvmx_helper_interface_enumerate(int xiface)1176 int cvmx_helper_interface_enumerate(int xiface)
1177 {
1178 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
1179 	int result = 0;
1180 
1181 	cvmx_helper_interface_get_mode(xiface);
1182 	if (iface_node_ops[xi.node][xi.interface]->enumerate)
1183 		result = iface_node_ops[xi.node][xi.interface]->enumerate(xiface);
1184 
1185 	return result;
1186 }
1187 
1188 /**
1189  * This function probes an interface to determine the actual number of
1190  * hardware ports connected to it. It does some setup the ports but
1191  * doesn't enable them. The main goal here is to set the global
1192  * interface_port_count[interface] correctly. Final hardware setup of
1193  * the ports will be performed later.
1194  *
1195  * @param xiface Interface to probe
1196  *
1197  * Return: Zero on success, negative on failure
1198  */
cvmx_helper_interface_probe(int xiface)1199 int cvmx_helper_interface_probe(int xiface)
1200 {
1201 	/*
1202 	 * At this stage in the game we don't want packets to be
1203 	 * moving yet.  The following probe calls should perform
1204 	 * hardware setup needed to determine port counts. Receive
1205 	 * must still be disabled.
1206 	 */
1207 	int nports;
1208 	int has_fcs;
1209 	enum cvmx_pko_padding padding = CVMX_PKO_PADDING_NONE;
1210 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
1211 
1212 	nports = -1;
1213 	has_fcs = 0;
1214 
1215 	cvmx_helper_interface_get_mode(xiface);
1216 	if (iface_node_ops[xi.node][xi.interface]->probe)
1217 		nports = iface_node_ops[xi.node][xi.interface]->probe(xiface);
1218 
1219 	switch (iface_node_ops[xi.node][xi.interface]->mode) {
1220 		/* These types don't support ports to IPD/PKO */
1221 	case CVMX_HELPER_INTERFACE_MODE_DISABLED:
1222 	case CVMX_HELPER_INTERFACE_MODE_PCIE:
1223 		nports = 0;
1224 		break;
1225 		/* XAUI is a single high speed port */
1226 	case CVMX_HELPER_INTERFACE_MODE_XAUI:
1227 	case CVMX_HELPER_INTERFACE_MODE_RXAUI:
1228 	case CVMX_HELPER_INTERFACE_MODE_XLAUI:
1229 	case CVMX_HELPER_INTERFACE_MODE_XFI:
1230 	case CVMX_HELPER_INTERFACE_MODE_10G_KR:
1231 	case CVMX_HELPER_INTERFACE_MODE_40G_KR4:
1232 	case CVMX_HELPER_INTERFACE_MODE_MIXED:
1233 		has_fcs = 1;
1234 		padding = CVMX_PKO_PADDING_60;
1235 		break;
1236 		/*
1237 		 * RGMII/GMII/MII are all treated about the same. Most
1238 		 * functions refer to these ports as RGMII.
1239 		 */
1240 	case CVMX_HELPER_INTERFACE_MODE_RGMII:
1241 	case CVMX_HELPER_INTERFACE_MODE_GMII:
1242 		padding = CVMX_PKO_PADDING_60;
1243 		break;
1244 		/*
1245 		 * SPI4 can have 1-16 ports depending on the device at
1246 		 * the other end.
1247 		 */
1248 	case CVMX_HELPER_INTERFACE_MODE_SPI:
1249 		padding = CVMX_PKO_PADDING_60;
1250 		break;
1251 		/*
1252 		 * SGMII can have 1-4 ports depending on how many are
1253 		 * hooked up.
1254 		 */
1255 	case CVMX_HELPER_INTERFACE_MODE_SGMII:
1256 	case CVMX_HELPER_INTERFACE_MODE_QSGMII:
1257 		padding = CVMX_PKO_PADDING_60;
1258 	case CVMX_HELPER_INTERFACE_MODE_PICMG:
1259 		has_fcs = 1;
1260 		break;
1261 		/* PCI target Network Packet Interface */
1262 	case CVMX_HELPER_INTERFACE_MODE_NPI:
1263 		break;
1264 		/*
1265 		 * Special loopback only ports. These are not the same
1266 		 * as other ports in loopback mode.
1267 		 */
1268 	case CVMX_HELPER_INTERFACE_MODE_LOOP:
1269 		break;
1270 		/* SRIO has 2^N ports, where N is number of interfaces */
1271 	case CVMX_HELPER_INTERFACE_MODE_SRIO:
1272 		break;
1273 	case CVMX_HELPER_INTERFACE_MODE_ILK:
1274 		padding = CVMX_PKO_PADDING_60;
1275 		has_fcs = 1;
1276 		break;
1277 	case CVMX_HELPER_INTERFACE_MODE_AGL:
1278 		has_fcs = 1;
1279 		break;
1280 	}
1281 
1282 	if (nports == -1)
1283 		return -1;
1284 
1285 	if (!octeon_has_feature(OCTEON_FEATURE_PKND))
1286 		has_fcs = 0;
1287 
1288 	nports = __cvmx_helper_board_interface_probe(xiface, nports);
1289 	__cvmx_helper_init_interface(xiface, nports, has_fcs, padding);
1290 	/* Make sure all global variables propagate to other cores */
1291 	CVMX_SYNCWS;
1292 
1293 	return 0;
1294 }
1295 
1296 /**
1297  * @INTERNAL
1298  * Setup backpressure.
1299  *
1300  * Return: Zero on success, negative on failure
1301  */
__cvmx_helper_global_setup_backpressure(int node)1302 static int __cvmx_helper_global_setup_backpressure(int node)
1303 {
1304 	cvmx_qos_proto_t qos_proto;
1305 	cvmx_qos_pkt_mode_t qos_mode;
1306 	int port, xipdport;
1307 	unsigned int bpmask;
1308 	int interface, xiface, ports;
1309 	int num_interfaces = cvmx_helper_get_number_of_interfaces();
1310 
1311 	if (cvmx_rgmii_backpressure_dis) {
1312 		qos_proto = CVMX_QOS_PROTO_NONE;
1313 		qos_mode = CVMX_QOS_PKT_MODE_DROP;
1314 	} else {
1315 		qos_proto = CVMX_QOS_PROTO_PAUSE;
1316 		qos_mode = CVMX_QOS_PKT_MODE_HWONLY;
1317 	}
1318 
1319 	for (interface = 0; interface < num_interfaces; interface++) {
1320 		xiface = cvmx_helper_node_interface_to_xiface(node, interface);
1321 		ports = cvmx_helper_ports_on_interface(xiface);
1322 
1323 		switch (cvmx_helper_interface_get_mode(xiface)) {
1324 		case CVMX_HELPER_INTERFACE_MODE_DISABLED:
1325 		case CVMX_HELPER_INTERFACE_MODE_PCIE:
1326 		case CVMX_HELPER_INTERFACE_MODE_SRIO:
1327 		case CVMX_HELPER_INTERFACE_MODE_ILK:
1328 		case CVMX_HELPER_INTERFACE_MODE_NPI:
1329 		case CVMX_HELPER_INTERFACE_MODE_PICMG:
1330 			break;
1331 		case CVMX_HELPER_INTERFACE_MODE_LOOP:
1332 		case CVMX_HELPER_INTERFACE_MODE_XAUI:
1333 		case CVMX_HELPER_INTERFACE_MODE_RXAUI:
1334 		case CVMX_HELPER_INTERFACE_MODE_XLAUI:
1335 		case CVMX_HELPER_INTERFACE_MODE_XFI:
1336 		case CVMX_HELPER_INTERFACE_MODE_10G_KR:
1337 		case CVMX_HELPER_INTERFACE_MODE_40G_KR4:
1338 			bpmask = (cvmx_rgmii_backpressure_dis) ? 0xF : 0;
1339 			if (octeon_has_feature(OCTEON_FEATURE_BGX)) {
1340 				for (port = 0; port < ports; port++) {
1341 					xipdport = cvmx_helper_get_ipd_port(xiface, port);
1342 					cvmx_bgx_set_flowctl_mode(xipdport, qos_proto, qos_mode);
1343 				}
1344 				cvmx_bgx_set_backpressure_override(xiface, bpmask);
1345 			}
1346 			break;
1347 		case CVMX_HELPER_INTERFACE_MODE_RGMII:
1348 		case CVMX_HELPER_INTERFACE_MODE_GMII:
1349 		case CVMX_HELPER_INTERFACE_MODE_SPI:
1350 		case CVMX_HELPER_INTERFACE_MODE_SGMII:
1351 		case CVMX_HELPER_INTERFACE_MODE_QSGMII:
1352 		case CVMX_HELPER_INTERFACE_MODE_MIXED:
1353 			bpmask = (cvmx_rgmii_backpressure_dis) ? 0xF : 0;
1354 			if (octeon_has_feature(OCTEON_FEATURE_BGX)) {
1355 				for (port = 0; port < ports; port++) {
1356 					xipdport = cvmx_helper_get_ipd_port(xiface, port);
1357 					cvmx_bgx_set_flowctl_mode(xipdport, qos_proto, qos_mode);
1358 				}
1359 				cvmx_bgx_set_backpressure_override(xiface, bpmask);
1360 			} else {
1361 				cvmx_gmx_set_backpressure_override(interface, bpmask);
1362 			}
1363 			break;
1364 		case CVMX_HELPER_INTERFACE_MODE_AGL:
1365 			bpmask = (cvmx_rgmii_backpressure_dis) ? 0x1 : 0;
1366 			cvmx_agl_set_backpressure_override(interface, bpmask);
1367 			break;
1368 		}
1369 	}
1370 	return 0;
1371 }
1372 
1373 /**
1374  * @INTERNAL
1375  * Enable packet input/output from the hardware. This function is
1376  * called after all internal setup is complete and IPD is enabled.
1377  * After this function completes, packets will be accepted from the
1378  * hardware ports. PKO should still be disabled to make sure packets
1379  * aren't sent out partially setup hardware.
1380  *
1381  * @param xiface Interface to enable
1382  *
1383  * Return: Zero on success, negative on failure
1384  */
__cvmx_helper_packet_hardware_enable(int xiface)1385 int __cvmx_helper_packet_hardware_enable(int xiface)
1386 {
1387 	int result = 0;
1388 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
1389 
1390 	if (iface_node_ops[xi.node][xi.interface]->enable)
1391 		result = iface_node_ops[xi.node][xi.interface]->enable(xiface);
1392 
1393 	return result;
1394 }
1395 
cvmx_helper_ipd_and_packet_input_enable(void)1396 int cvmx_helper_ipd_and_packet_input_enable(void)
1397 {
1398 	return cvmx_helper_ipd_and_packet_input_enable_node(cvmx_get_node_num());
1399 }
1400 
1401 /**
1402  * Called after all internal packet IO paths are setup. This
1403  * function enables IPD/PIP and begins packet input and output.
1404  *
1405  * Return: Zero on success, negative on failure
1406  */
cvmx_helper_ipd_and_packet_input_enable_node(int node)1407 int cvmx_helper_ipd_and_packet_input_enable_node(int node)
1408 {
1409 	int num_interfaces;
1410 	int interface;
1411 	int num_ports;
1412 
1413 	if (octeon_has_feature(OCTEON_FEATURE_PKI)) {
1414 		cvmx_helper_pki_enable(node);
1415 	} else {
1416 		/* Enable IPD */
1417 		cvmx_ipd_enable();
1418 	}
1419 
1420 	/*
1421 	 * Time to enable hardware ports packet input and output. Note
1422 	 * that at this point IPD/PIP must be fully functional and PKO
1423 	 * must be disabled .
1424 	 */
1425 	num_interfaces = cvmx_helper_get_number_of_interfaces();
1426 	for (interface = 0; interface < num_interfaces; interface++) {
1427 		int xiface = cvmx_helper_node_interface_to_xiface(node, interface);
1428 
1429 		num_ports = cvmx_helper_ports_on_interface(xiface);
1430 		if (num_ports > 0)
1431 			__cvmx_helper_packet_hardware_enable(xiface);
1432 	}
1433 
1434 	/* Finally enable PKO now that the entire path is up and running */
1435 	/* enable pko */
1436 	if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE))
1437 		; // cvmx_pko_enable_78xx(0); already enabled
1438 	else
1439 		cvmx_pko_enable();
1440 
1441 	return 0;
1442 }
1443 
1444 /**
1445  * Initialize the PIP, IPD, and PKO hardware to support
1446  * simple priority based queues for the ethernet ports. Each
1447  * port is configured with a number of priority queues based
1448  * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
1449  * priority than the previous.
1450  *
1451  * Return: Zero on success, non-zero on failure
1452  */
cvmx_helper_initialize_packet_io_node(unsigned int node)1453 int cvmx_helper_initialize_packet_io_node(unsigned int node)
1454 {
1455 	int result = 0;
1456 	int interface;
1457 	int xiface;
1458 	union cvmx_l2c_cfg l2c_cfg;
1459 	union cvmx_smix_en smix_en;
1460 	const int num_interfaces = cvmx_helper_get_number_of_interfaces();
1461 
1462 	/*
1463 	 * Tell L2 to give the IOB statically higher priority compared
1464 	 * to the cores. This avoids conditions where IO blocks might
1465 	 * be starved under very high L2 loads.
1466 	 */
1467 	if (OCTEON_IS_OCTEON2() || OCTEON_IS_OCTEON3()) {
1468 		union cvmx_l2c_ctl l2c_ctl;
1469 
1470 		l2c_ctl.u64 = csr_rd_node(node, CVMX_L2C_CTL);
1471 		l2c_ctl.s.rsp_arb_mode = 1;
1472 		l2c_ctl.s.xmc_arb_mode = 0;
1473 		csr_wr_node(node, CVMX_L2C_CTL, l2c_ctl.u64);
1474 	} else {
1475 		l2c_cfg.u64 = csr_rd(CVMX_L2C_CFG);
1476 		l2c_cfg.s.lrf_arb_mode = 0;
1477 		l2c_cfg.s.rfb_arb_mode = 0;
1478 		csr_wr(CVMX_L2C_CFG, l2c_cfg.u64);
1479 	}
1480 
1481 	int smi_inf;
1482 	int i;
1483 
1484 	/* Newer chips have more than one SMI/MDIO interface */
1485 	if (OCTEON_IS_MODEL(OCTEON_CN68XX) || OCTEON_IS_MODEL(OCTEON_CN78XX))
1486 		smi_inf = 4;
1487 	else if (OCTEON_IS_MODEL(OCTEON_CN73XX) || OCTEON_IS_MODEL(OCTEON_CNF75XX))
1488 		smi_inf = 2;
1489 	else
1490 		smi_inf = 2;
1491 
1492 	for (i = 0; i < smi_inf; i++) {
1493 		/* Make sure SMI/MDIO is enabled so we can query PHYs */
1494 		smix_en.u64 = csr_rd_node(node, CVMX_SMIX_EN(i));
1495 		if (!smix_en.s.en) {
1496 			smix_en.s.en = 1;
1497 			csr_wr_node(node, CVMX_SMIX_EN(i), smix_en.u64);
1498 		}
1499 	}
1500 
1501 	//vinita_to_do ask it need to be modify for multinode
1502 	__cvmx_helper_init_port_valid();
1503 
1504 	for (interface = 0; interface < num_interfaces; interface++) {
1505 		xiface = cvmx_helper_node_interface_to_xiface(node, interface);
1506 		result |= cvmx_helper_interface_probe(xiface);
1507 	}
1508 
1509 	/* PKO3 init precedes that of interfaces */
1510 	if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {
1511 		__cvmx_helper_init_port_config_data(node);
1512 		result = cvmx_helper_pko3_init_global(node);
1513 	} else {
1514 		result = cvmx_helper_pko_init();
1515 	}
1516 
1517 	/* Errata SSO-29000, Disabling power saving SSO conditional clocking */
1518 	if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {
1519 		cvmx_sso_ws_cfg_t cfg;
1520 
1521 		cfg.u64 = csr_rd_node(node, CVMX_SSO_WS_CFG);
1522 		cfg.s.sso_cclk_dis = 1;
1523 		csr_wr_node(node, CVMX_SSO_WS_CFG, cfg.u64);
1524 	}
1525 
1526 	if (result < 0)
1527 		return result;
1528 
1529 	for (interface = 0; interface < num_interfaces; interface++) {
1530 		xiface = cvmx_helper_node_interface_to_xiface(node, interface);
1531 		/* Skip invalid/disabled interfaces */
1532 		if (cvmx_helper_ports_on_interface(xiface) <= 0)
1533 			continue;
1534 		debug("Node %d Interface %d has %d ports (%s)\n",
1535 		      node, interface,
1536 		       cvmx_helper_ports_on_interface(xiface),
1537 		       cvmx_helper_interface_mode_to_string(
1538 			       cvmx_helper_interface_get_mode(xiface)));
1539 
1540 		result |= __cvmx_helper_ipd_setup_interface(xiface);
1541 		if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE))
1542 			result |= cvmx_helper_pko3_init_interface(xiface);
1543 		else
1544 			result |= __cvmx_helper_interface_setup_pko(interface);
1545 	}
1546 
1547 	if (octeon_has_feature(OCTEON_FEATURE_PKI))
1548 		result |= __cvmx_helper_pki_global_setup(node);
1549 	else
1550 		result |= __cvmx_helper_ipd_global_setup();
1551 
1552 	/* Enable any flow control and backpressure */
1553 	result |= __cvmx_helper_global_setup_backpressure(node);
1554 
1555 	/* export app config if set */
1556 	if (cvmx_export_app_config)
1557 		result |= (*cvmx_export_app_config)();
1558 
1559 	if (cvmx_ipd_cfg.ipd_enable && cvmx_pki_dflt_init[node])
1560 		result |= cvmx_helper_ipd_and_packet_input_enable_node(node);
1561 	return result;
1562 }
1563 
1564 /**
1565  * Initialize the PIP, IPD, and PKO hardware to support
1566  * simple priority based queues for the ethernet ports. Each
1567  * port is configured with a number of priority queues based
1568  * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
1569  * priority than the previous.
1570  *
1571  * Return: Zero on success, non-zero on failure
1572  */
cvmx_helper_initialize_packet_io_global(void)1573 int cvmx_helper_initialize_packet_io_global(void)
1574 {
1575 	unsigned int node = cvmx_get_node_num();
1576 
1577 	return cvmx_helper_initialize_packet_io_node(node);
1578 }
1579 
1580 /**
1581  * Does core local initialization for packet io
1582  *
1583  * Return: Zero on success, non-zero on failure
1584  */
cvmx_helper_initialize_packet_io_local(void)1585 int cvmx_helper_initialize_packet_io_local(void)
1586 {
1587 	if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE))
1588 		__cvmx_pko3_dq_table_setup();
1589 
1590 	return 0;
1591 }
1592 
1593 struct cvmx_buffer_list {
1594 	struct cvmx_buffer_list *next;
1595 };
1596 
1597 /**
1598  * Disables the sending of flow control (pause) frames on the specified
1599  * GMX port(s).
1600  *
1601  * @param interface Which interface (0 or 1)
1602  * @param port_mask Mask (4bits) of which ports on the interface to disable
1603  *                  backpressure on.
1604  *                  1 => disable backpressure
1605  *                  0 => enable backpressure
1606  *
1607  * Return: 0 on success
1608  *         -1 on error
1609  */
cvmx_gmx_set_backpressure_override(u32 interface,uint32_t port_mask)1610 int cvmx_gmx_set_backpressure_override(u32 interface, uint32_t port_mask)
1611 {
1612 	union cvmx_gmxx_tx_ovr_bp gmxx_tx_ovr_bp;
1613 	/* Check for valid arguments */
1614 	if (port_mask & ~0xf || interface & ~0x1)
1615 		return -1;
1616 	if (interface >= CVMX_HELPER_MAX_GMX)
1617 		return -1;
1618 
1619 	gmxx_tx_ovr_bp.u64 = 0;
1620 	gmxx_tx_ovr_bp.s.en = port_mask;       /* Per port Enable back pressure override */
1621 	gmxx_tx_ovr_bp.s.ign_full = port_mask; /* Ignore the RX FIFO full when computing BP */
1622 	csr_wr(CVMX_GMXX_TX_OVR_BP(interface), gmxx_tx_ovr_bp.u64);
1623 	return 0;
1624 }
1625 
1626 /**
1627  * Disables the sending of flow control (pause) frames on the specified
1628  * AGL (RGMII) port(s).
1629  *
1630  * @param interface Which interface (0 or 1)
1631  * @param port_mask Mask (4bits) of which ports on the interface to disable
1632  *                  backpressure on.
1633  *                  1 => disable backpressure
1634  *                  0 => enable backpressure
1635  *
1636  * Return: 0 on success
1637  *         -1 on error
1638  */
cvmx_agl_set_backpressure_override(u32 interface,uint32_t port_mask)1639 int cvmx_agl_set_backpressure_override(u32 interface, uint32_t port_mask)
1640 {
1641 	union cvmx_agl_gmx_tx_ovr_bp agl_gmx_tx_ovr_bp;
1642 	int port = cvmx_helper_agl_get_port(interface);
1643 
1644 	if (port == -1)
1645 		return -1;
1646 	/* Check for valid arguments */
1647 	agl_gmx_tx_ovr_bp.u64 = 0;
1648 	/* Per port Enable back pressure override */
1649 	agl_gmx_tx_ovr_bp.s.en = port_mask;
1650 	/* Ignore the RX FIFO full when computing BP */
1651 	agl_gmx_tx_ovr_bp.s.ign_full = port_mask;
1652 	csr_wr(CVMX_GMXX_TX_OVR_BP(port), agl_gmx_tx_ovr_bp.u64);
1653 	return 0;
1654 }
1655 
1656 /**
1657  * Auto configure an IPD/PKO port link state and speed. This
1658  * function basically does the equivalent of:
1659  * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
1660  *
1661  * @param xipd_port IPD/PKO port to auto configure
1662  *
1663  * Return: Link state after configure
1664  */
cvmx_helper_link_autoconf(int xipd_port)1665 cvmx_helper_link_info_t cvmx_helper_link_autoconf(int xipd_port)
1666 {
1667 	cvmx_helper_link_info_t link_info;
1668 	int xiface = cvmx_helper_get_interface_num(xipd_port);
1669 	int index = cvmx_helper_get_interface_index_num(xipd_port);
1670 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
1671 	int interface = xi.interface;
1672 
1673 	if (interface == -1 || index == -1 || index >= cvmx_helper_ports_on_interface(xiface)) {
1674 		link_info.u64 = 0;
1675 		return link_info;
1676 	}
1677 
1678 	link_info = cvmx_helper_link_get(xipd_port);
1679 	if (link_info.u64 == (__cvmx_helper_get_link_info(xiface, index)).u64)
1680 		return link_info;
1681 
1682 	if (!link_info.s.link_up)
1683 		cvmx_error_disable_group(CVMX_ERROR_GROUP_ETHERNET, xipd_port);
1684 
1685 	/* If we fail to set the link speed, port_link_info will not change */
1686 	cvmx_helper_link_set(xipd_port, link_info);
1687 
1688 	if (link_info.s.link_up)
1689 		cvmx_error_enable_group(CVMX_ERROR_GROUP_ETHERNET, xipd_port);
1690 
1691 	return link_info;
1692 }
1693 
1694 /**
1695  * Return the link state of an IPD/PKO port as returned by
1696  * auto negotiation. The result of this function may not match
1697  * Octeon's link config if auto negotiation has changed since
1698  * the last call to cvmx_helper_link_set().
1699  *
1700  * @param xipd_port IPD/PKO port to query
1701  *
1702  * Return: Link state
1703  */
cvmx_helper_link_get(int xipd_port)1704 cvmx_helper_link_info_t cvmx_helper_link_get(int xipd_port)
1705 {
1706 	cvmx_helper_link_info_t result;
1707 	int xiface = cvmx_helper_get_interface_num(xipd_port);
1708 	int index = cvmx_helper_get_interface_index_num(xipd_port);
1709 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
1710 	struct cvmx_fdt_sfp_info *sfp_info;
1711 
1712 	/*
1713 	 * The default result will be a down link unless the code
1714 	 * below changes it.
1715 	 */
1716 	result.u64 = 0;
1717 
1718 	if (__cvmx_helper_xiface_is_null(xiface) || index == -1 ||
1719 	    index >= cvmx_helper_ports_on_interface(xiface)) {
1720 		return result;
1721 	}
1722 
1723 	if (iface_node_ops[xi.node][xi.interface]->link_get)
1724 		result = iface_node_ops[xi.node][xi.interface]->link_get(xipd_port);
1725 
1726 	if (xipd_port >= 0) {
1727 		cvmx_helper_update_link_led(xiface, index, result);
1728 
1729 		sfp_info = cvmx_helper_cfg_get_sfp_info(xiface, index);
1730 
1731 		while (sfp_info) {
1732 			if ((!result.s.link_up || (result.s.link_up && sfp_info->last_mod_abs)))
1733 				cvmx_sfp_check_mod_abs(sfp_info, sfp_info->mod_abs_data);
1734 			sfp_info = sfp_info->next_iface_sfp;
1735 		}
1736 	}
1737 
1738 	return result;
1739 }
1740 
1741 /**
1742  * Configure an IPD/PKO port for the specified link state. This
1743  * function does not influence auto negotiation at the PHY level.
1744  * The passed link state must always match the link state returned
1745  * by cvmx_helper_link_get(). It is normally best to use
1746  * cvmx_helper_link_autoconf() instead.
1747  *
1748  * @param xipd_port  IPD/PKO port to configure
1749  * @param link_info The new link state
1750  *
1751  * Return: Zero on success, negative on failure
1752  */
cvmx_helper_link_set(int xipd_port,cvmx_helper_link_info_t link_info)1753 int cvmx_helper_link_set(int xipd_port, cvmx_helper_link_info_t link_info)
1754 {
1755 	int result = -1;
1756 	int xiface = cvmx_helper_get_interface_num(xipd_port);
1757 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
1758 	int index = cvmx_helper_get_interface_index_num(xipd_port);
1759 
1760 	if (__cvmx_helper_xiface_is_null(xiface) || index == -1 ||
1761 	    index >= cvmx_helper_ports_on_interface(xiface))
1762 		return -1;
1763 
1764 	if (iface_node_ops[xi.node][xi.interface]->link_set)
1765 		result = iface_node_ops[xi.node][xi.interface]->link_set(xipd_port, link_info);
1766 
1767 	/*
1768 	 * Set the port_link_info here so that the link status is
1769 	 * updated no matter how cvmx_helper_link_set is called. We
1770 	 * don't change the value if link_set failed.
1771 	 */
1772 	if (result == 0)
1773 		__cvmx_helper_set_link_info(xiface, index, link_info);
1774 	return result;
1775 }
1776 
cvmx_helper_mem_alloc(int node,uint64_t alloc_size,uint64_t align)1777 void *cvmx_helper_mem_alloc(int node, uint64_t alloc_size, uint64_t align)
1778 {
1779 	s64 paddr;
1780 
1781 	paddr = cvmx_bootmem_phy_alloc_range(alloc_size, align, cvmx_addr_on_node(node, 0ull),
1782 					     cvmx_addr_on_node(node, 0xffffffffff));
1783 	if (paddr <= 0ll) {
1784 		printf("ERROR: %s failed size %u\n", __func__, (unsigned int)alloc_size);
1785 		return NULL;
1786 	}
1787 	return cvmx_phys_to_ptr(paddr);
1788 }
1789