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
47static 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 */
59int __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 */
81int __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