1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2018-2022 Marvell International Ltd.
4  *
5  * Functions for NPI initialization, configuration,
6  * and monitoring.
7  */
8 
9 #include <time.h>
10 #include <log.h>
11 #include <linux/delay.h>
12 
13 #include <mach/cvmx-regs.h>
14 #include <mach/cvmx-csr.h>
15 #include <mach/cvmx-bootmem.h>
16 #include <mach/octeon-model.h>
17 #include <mach/cvmx-fuse.h>
18 #include <mach/octeon-feature.h>
19 #include <mach/cvmx-qlm.h>
20 #include <mach/octeon_qlm.h>
21 #include <mach/cvmx-pcie.h>
22 #include <mach/cvmx-coremask.h>
23 
24 #include <mach/cvmx-agl-defs.h>
25 #include <mach/cvmx-bgxx-defs.h>
26 #include <mach/cvmx-ciu-defs.h>
27 #include <mach/cvmx-gmxx-defs.h>
28 #include <mach/cvmx-gserx-defs.h>
29 #include <mach/cvmx-ilk-defs.h>
30 #include <mach/cvmx-ipd-defs.h>
31 #include <mach/cvmx-pexp-defs.h>
32 #include <mach/cvmx-pcsx-defs.h>
33 #include <mach/cvmx-pcsxx-defs.h>
34 #include <mach/cvmx-pki-defs.h>
35 #include <mach/cvmx-pko-defs.h>
36 #include <mach/cvmx-sli-defs.h>
37 #include <mach/cvmx-xcv-defs.h>
38 
39 #include <mach/cvmx-hwpko.h>
40 #include <mach/cvmx-ilk.h>
41 #include <mach/cvmx-pki.h>
42 
43 #include <mach/cvmx-helper.h>
44 #include <mach/cvmx-helper-board.h>
45 #include <mach/cvmx-helper-cfg.h>
46 
47 static int cvmx_npi_num_pipes = -1;
48 
49 /**
50  * @INTERNAL
51  * Probe a NPI interface and determine the number of ports
52  * connected to it. The NPI interface should still be down
53  * after this call.
54  *
55  * @param interface to probe
56  *
57  * @return Number of ports on the interface. Zero to disable.
58  */
__cvmx_helper_npi_probe(int interface)59 int __cvmx_helper_npi_probe(int interface)
60 {
61 	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
62 		return 32;
63 	else if (OCTEON_IS_MODEL(OCTEON_CN73XX))
64 		return 128;
65 	else if (OCTEON_IS_MODEL(OCTEON_CN78XX))
66 		return 64;
67 
68 	return 0;
69 }
70 
71 /**
72  * @INTERNAL
73  * Bringup and enable a NPI interface. After this call packet
74  * I/O should be fully functional. This is called with IPD
75  * enabled but PKO disabled.
76  *
77  * @param xiface Interface to bring up
78  *
79  * @return Zero on success, negative on failure
80  */
__cvmx_helper_npi_enable(int xiface)81 int __cvmx_helper_npi_enable(int xiface)
82 {
83 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
84 	int interface = xi.interface;
85 	int port;
86 	int num_ports = cvmx_helper_ports_on_interface(interface);
87 
88 	/*
89 	 * On CN50XX, CN52XX, and CN56XX we need to disable length
90 	 * checking so packet < 64 bytes and jumbo frames don't get
91 	 * errors.
92 	 */
93 	for (port = 0; port < num_ports; port++) {
94 		union cvmx_pip_prt_cfgx port_cfg;
95 		int ipd_port =
96 			(octeon_has_feature(OCTEON_FEATURE_PKND)) ?
97 				cvmx_helper_get_pknd(interface, port) :
98 				      cvmx_helper_get_ipd_port(interface, port);
99 		if (octeon_has_feature(OCTEON_FEATURE_PKI)) {
100 			unsigned int node = cvmx_get_node_num();
101 
102 			cvmx_pki_endis_l2_errs(node, ipd_port, 0, 0, 0);
103 
104 		} else {
105 			port_cfg.u64 = csr_rd(CVMX_PIP_PRT_CFGX(ipd_port));
106 			port_cfg.s.lenerr_en = 0;
107 			port_cfg.s.maxerr_en = 0;
108 			port_cfg.s.minerr_en = 0;
109 			csr_wr(CVMX_PIP_PRT_CFGX(ipd_port), port_cfg.u64);
110 		}
111 		if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
112 			/* Set up pknd and bpid */
113 			union cvmx_sli_portx_pkind config;
114 
115 			config.u64 = csr_rd(CVMX_PEXP_SLI_PORTX_PKIND(port));
116 			config.s.bpkind = cvmx_helper_get_bpid(interface, port);
117 			config.s.pkind = cvmx_helper_get_pknd(interface, port);
118 			csr_wr(CVMX_PEXP_SLI_PORTX_PKIND(port), config.u64);
119 		}
120 	}
121 
122 	if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
123 		/*
124 		 * Set up pko pipes.
125 		 */
126 		union cvmx_sli_tx_pipe config;
127 
128 		config.u64 = csr_rd(CVMX_PEXP_SLI_TX_PIPE);
129 		config.s.base = __cvmx_pko_get_pipe(interface, 0);
130 		config.s.nump =
131 			cvmx_npi_num_pipes < 0 ? num_ports : cvmx_npi_num_pipes;
132 		csr_wr(CVMX_PEXP_SLI_TX_PIPE, config.u64);
133 	}
134 
135 	/* Enables are controlled by the remote host, so nothing to do here */
136 	return 0;
137 }
138