1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2018-2022 Marvell International Ltd.
4 *
5 * Helper Functions for the PKO
6 */
7
8 #include <errno.h>
9 #include <log.h>
10 #include <time.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 #include <mach/cvmx-range.h>
24 #include <mach/cvmx-global-resources.h>
25
26 #include <mach/cvmx-agl-defs.h>
27 #include <mach/cvmx-bgxx-defs.h>
28 #include <mach/cvmx-ciu-defs.h>
29 #include <mach/cvmx-gmxx-defs.h>
30 #include <mach/cvmx-gserx-defs.h>
31 #include <mach/cvmx-ilk-defs.h>
32 #include <mach/cvmx-ipd-defs.h>
33 #include <mach/cvmx-pcsx-defs.h>
34 #include <mach/cvmx-pcsxx-defs.h>
35 #include <mach/cvmx-pki-defs.h>
36 #include <mach/cvmx-pko-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-ipd.h>
42 #include <mach/cvmx-pki.h>
43 #include <mach/cvmx-pko3.h>
44 #include <mach/cvmx-pko3-queue.h>
45 #include <mach/cvmx-pko3-resources.h>
46
47 #include <mach/cvmx-helper.h>
48 #include <mach/cvmx-helper-board.h>
49 #include <mach/cvmx-helper-cfg.h>
50
51 #include <mach/cvmx-helper-bgx.h>
52 #include <mach/cvmx-helper-cfg.h>
53 #include <mach/cvmx-helper-util.h>
54 #include <mach/cvmx-helper-pki.h>
55
56 static s64 pko_fpa_config_pool = -1;
57 static u64 pko_fpa_config_size = 1024;
58
59 /**
60 * cvmx_override_pko_queue_priority(int pko_port, u64
61 * priorities[16]) is a function pointer. It is meant to allow
62 * customization of the PKO queue priorities based on the port
63 * number. Users should set this pointer to a function before
64 * calling any cvmx-helper operations.
65 */
66 void (*cvmx_override_pko_queue_priority)(int ipd_port,
67 uint8_t *priorities) = NULL;
68
cvmx_fpa_get_pko_pool(void)69 int64_t cvmx_fpa_get_pko_pool(void)
70 {
71 return pko_fpa_config_pool;
72 }
73
74 /**
75 * Gets the buffer size of pko pool
76 */
cvmx_fpa_get_pko_pool_block_size(void)77 u64 cvmx_fpa_get_pko_pool_block_size(void)
78 {
79 return pko_fpa_config_size;
80 }
81
82 /**
83 * Initialize PKO command queue buffer pool
84 */
cvmx_helper_pko_pool_init(void)85 static int cvmx_helper_pko_pool_init(void)
86 {
87 u8 pool;
88 unsigned int buf_count;
89 unsigned int pkt_buf_count;
90 int rc;
91
92 /* Reserve pool */
93 pool = cvmx_fpa_get_pko_pool();
94
95 /* Avoid redundant pool creation */
96 if (cvmx_fpa_get_block_size(pool) > 0) {
97 #ifdef DEBUG
98 debug("WARNING: %s: pool %d already initialized\n", __func__,
99 pool);
100 #endif
101 /* It is up to the app to have sufficient buffer count */
102 return pool;
103 }
104
105 /* Calculate buffer count: one per queue + 3-word-cmds * max_pkts */
106 pkt_buf_count = cvmx_fpa_get_packet_pool_buffer_count();
107 buf_count = CVMX_PKO_MAX_OUTPUT_QUEUES + (pkt_buf_count * 3) / 8;
108
109 /* Allocate pools for pko command queues */
110 rc = __cvmx_helper_initialize_fpa_pool(pool,
111 cvmx_fpa_get_pko_pool_block_size(),
112 buf_count, "PKO Cmd-bufs");
113
114 if (rc < 0)
115 debug("%s: ERROR: in PKO buffer pool\n", __func__);
116
117 pool = rc;
118 return pool;
119 }
120
121 /**
122 * Initialize the PKO
123 *
124 */
cvmx_helper_pko_init(void)125 int cvmx_helper_pko_init(void)
126 {
127 int rc;
128
129 rc = cvmx_helper_pko_pool_init();
130 if (rc < 0)
131 return rc;
132
133 __cvmx_helper_init_port_config_data(0);
134
135 cvmx_pko_hw_init(cvmx_fpa_get_pko_pool(),
136 cvmx_fpa_get_pko_pool_block_size());
137 return 0;
138 }
139
140 /**
141 * @INTERNAL
142 * Setup the PKO for the ports on an interface. The number of
143 * queues per port and the priority of each PKO output queue
144 * is set here. PKO must be disabled when this function is called.
145 *
146 * @param interface to setup PKO for
147 *
148 * @return Zero on success, negative on failure
149 *
150 * @note This is for PKO1/PKO2, and is not used for PKO3.
151 */
__cvmx_helper_interface_setup_pko(int interface)152 int __cvmx_helper_interface_setup_pko(int interface)
153 {
154 /*
155 * Each packet output queue has an associated priority. The
156 * higher the priority, the more often it can send a packet. A
157 * priority of 8 means it can send in all 8 rounds of
158 * contention. We're going to make each queue one less than
159 * the last. The vector of priorities has been extended to
160 * support CN5xxx CPUs, where up to 16 queues can be
161 * associated to a port. To keep backward compatibility we
162 * don't change the initial 8 priorities and replicate them in
163 * the second half. With per-core PKO queues (PKO lockless
164 * operation) all queues have the same priority.
165 */
166 /* uint8_t priorities[16] = {8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1}; */
167 u8 priorities[16] = { [0 ... 15] = 8 };
168
169 /*
170 * Setup the IPD/PIP and PKO for the ports discovered
171 * above. Here packet classification, tagging and output
172 * priorities are set.
173 */
174 int num_ports = cvmx_helper_ports_on_interface(interface);
175
176 while (num_ports--) {
177 int ipd_port;
178
179 if (!cvmx_helper_is_port_valid(interface, num_ports))
180 continue;
181
182 ipd_port = cvmx_helper_get_ipd_port(interface, num_ports);
183 /*
184 * Give the user a chance to override the per queue
185 * priorities.
186 */
187 if (cvmx_override_pko_queue_priority)
188 cvmx_override_pko_queue_priority(ipd_port, priorities);
189
190 cvmx_pko_config_port(ipd_port,
191 cvmx_pko_get_base_queue(ipd_port),
192 cvmx_pko_get_num_queues(ipd_port),
193 priorities);
194 ipd_port++;
195 }
196 return 0;
197 /* NOTE:
198 * Now this function is called for all chips including 68xx,
199 * but on the 68xx it does not enable multiple pko_iports per
200 * eport, while before it was doing 3 pko_iport per eport
201 * buf the reason for that is not clear.
202 */
203 }
204