blob: 26e7a9adf4b3fa58ac4d9178ddc883e05f16ff4c [file] [log] [blame]
Aaron Williams1fd14ee2022-04-07 09:11:03 +02001/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2018-2022 Marvell International Ltd.
4 *
5 * Backward compatibility for packet transmission using legacy PKO command.
6 */
7
8#ifndef __CVMX_PKO_H__
9#define __CVMX_PKO_H__
10
11extern cvmx_pko_return_value_t
12cvmx_pko3_legacy_xmit(unsigned int dq, cvmx_pko_command_word0_t pko_command,
13 cvmx_buf_ptr_t packet, uint64_t addr, bool tag_sw);
14
15/**
16 * Complete packet output. cvmx_pko_send_packet_prepare() must be called exactly
17 * once before this, and the same parameters must be passed to both
18 * cvmx_pko_send_packet_prepare() and cvmx_pko_send_packet_finish().
19 *
20 * WARNING: This function may have to look up the proper PKO port in
21 * the IPD port to PKO port map, and is thus slower than calling
22 * cvmx_pko_send_packet_finish_pkoid() directly if the PKO port
23 * identifier is known.
24 *
25 * @param ipd_port The IPD port corresponding the to pko port the packet is for
26 * @param queue Queue to use
27 * @param pko_command
28 * PKO HW command word
29 * @param packet to send
30 * @param use_locking
31 * CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG,
32 * or CVMX_PKO_LOCK_CMD_QUEUE
33 *
34 * @return returns CVMX_PKO_SUCCESS on success, or error code on failure of output
35 */
36static inline cvmx_pko_return_value_t
37cvmx_pko_send_packet_finish(u64 ipd_port, uint64_t queue,
38 cvmx_pko_command_word0_t pko_command,
39 cvmx_buf_ptr_t packet, cvmx_pko_lock_t use_locking)
40{
41 cvmx_cmd_queue_result_t result;
42
43 if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {
44 return cvmx_pko3_legacy_xmit(queue, pko_command, packet, 0,
45 use_locking ==
46 CVMX_PKO_LOCK_ATOMIC_TAG);
47 }
48
49 if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
50 cvmx_pow_tag_sw_wait();
51
52 result = cvmx_cmd_queue_write2(CVMX_CMD_QUEUE_PKO(queue),
53 (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
54 pko_command.u64, packet.u64);
55 if (cvmx_likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
56 cvmx_pko_doorbell(ipd_port, queue, 2);
57 return CVMX_PKO_SUCCESS;
58 } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY) ||
59 (result == CVMX_CMD_QUEUE_FULL)) {
60 return CVMX_PKO_NO_MEMORY;
61 } else {
62 return CVMX_PKO_INVALID_QUEUE;
63 }
64}
65
66/**
67 * Complete packet output. cvmx_pko_send_packet_prepare() must be called exactly
68 * once before this, and the same parameters must be passed to both
69 * cvmx_pko_send_packet_prepare() and cvmx_pko_send_packet_finish().
70 *
71 * WARNING: This function may have to look up the proper PKO port in
72 * the IPD port to PKO port map, and is thus slower than calling
73 * cvmx_pko_send_packet_finish3_pkoid() directly if the PKO port
74 * identifier is known.
75 *
76 * @param ipd_port The IPD port corresponding the to pko port the packet is for
77 * @param queue Queue to use
78 * @param pko_command
79 * PKO HW command word
80 * @param packet to send
81 * @param addr Physical address of a work queue entry or physical address to zero
82 * on complete.
83 * @param use_locking
84 * CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG,
85 * or CVMX_PKO_LOCK_CMD_QUEUE
86 *
87 * @return returns CVMX_PKO_SUCCESS on success, or error code on failure of output
88 */
89static inline cvmx_pko_return_value_t
90cvmx_pko_send_packet_finish3(u64 ipd_port, uint64_t queue,
91 cvmx_pko_command_word0_t pko_command,
92 cvmx_buf_ptr_t packet, uint64_t addr,
93 cvmx_pko_lock_t use_locking)
94{
95 cvmx_cmd_queue_result_t result;
96
97 if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {
98 return cvmx_pko3_legacy_xmit(queue, pko_command, packet, addr,
99 use_locking ==
100 CVMX_PKO_LOCK_ATOMIC_TAG);
101 }
102
103 if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
104 cvmx_pow_tag_sw_wait();
105
106 result = cvmx_cmd_queue_write3(CVMX_CMD_QUEUE_PKO(queue),
107 (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
108 pko_command.u64, packet.u64, addr);
109 if (cvmx_likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
110 cvmx_pko_doorbell(ipd_port, queue, 3);
111 return CVMX_PKO_SUCCESS;
112 } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY) ||
113 (result == CVMX_CMD_QUEUE_FULL)) {
114 return CVMX_PKO_NO_MEMORY;
115 } else {
116 return CVMX_PKO_INVALID_QUEUE;
117 }
118}
119
120/**
121 * Complete packet output. cvmx_pko_send_packet_prepare() must be called exactly
122 * once before this, and the same parameters must be passed to both
123 * cvmx_pko_send_packet_prepare() and cvmx_pko_send_packet_finish_pkoid().
124 *
125 * @param pko_port Port to send it on
126 * @param queue Queue to use
127 * @param pko_command
128 * PKO HW command word
129 * @param packet to send
130 * @param use_locking
131 * CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG,
132 * or CVMX_PKO_LOCK_CMD_QUEUE
133 *
134 * @return returns CVMX_PKO_SUCCESS on success, or error code on failure of output
135 */
136static inline cvmx_pko_return_value_t
137cvmx_pko_send_packet_finish_pkoid(int pko_port, uint64_t queue,
138 cvmx_pko_command_word0_t pko_command,
139 cvmx_buf_ptr_t packet, cvmx_pko_lock_t use_locking)
140{
141 cvmx_cmd_queue_result_t result;
142
143 if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {
144 return cvmx_pko3_legacy_xmit(queue, pko_command, packet, 0,
145 use_locking ==
146 CVMX_PKO_LOCK_ATOMIC_TAG);
147 }
148
149 if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
150 cvmx_pow_tag_sw_wait();
151 result = cvmx_cmd_queue_write2(CVMX_CMD_QUEUE_PKO(queue),
152 (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
153 pko_command.u64, packet.u64);
154 if (cvmx_likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
155 cvmx_pko_doorbell_pkoid(pko_port, queue, 2);
156 return CVMX_PKO_SUCCESS;
157 } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY) ||
158 (result == CVMX_CMD_QUEUE_FULL)) {
159 return CVMX_PKO_NO_MEMORY;
160 } else {
161 return CVMX_PKO_INVALID_QUEUE;
162 }
163}
164
165/**
166 * Complete packet output. cvmx_pko_send_packet_prepare() must be called exactly
167 * once before this, and the same parameters must be passed to both
168 * cvmx_pko_send_packet_prepare() and cvmx_pko_send_packet_finish_pkoid().
169 *
170 * @param pko_port The PKO port the packet is for
171 * @param queue Queue to use
172 * @param pko_command
173 * PKO HW command word
174 * @param packet to send
175 * @param addr Plysical address of a work queue entry or physical address to zero
176 * on complete.
177 * @param use_locking
178 * CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG,
179 * or CVMX_PKO_LOCK_CMD_QUEUE
180 *
181 * @return returns CVMX_PKO_SUCCESS on success, or error code on failure of output
182 */
183static inline cvmx_pko_return_value_t
184cvmx_pko_send_packet_finish3_pkoid(u64 pko_port, uint64_t queue,
185 cvmx_pko_command_word0_t pko_command,
186 cvmx_buf_ptr_t packet, uint64_t addr,
187 cvmx_pko_lock_t use_locking)
188{
189 cvmx_cmd_queue_result_t result;
190
191 if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {
192 return cvmx_pko3_legacy_xmit(queue, pko_command, packet, addr,
193 use_locking ==
194 CVMX_PKO_LOCK_ATOMIC_TAG);
195 }
196
197 if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
198 cvmx_pow_tag_sw_wait();
199 result = cvmx_cmd_queue_write3(CVMX_CMD_QUEUE_PKO(queue),
200 (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
201 pko_command.u64, packet.u64, addr);
202 if (cvmx_likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
203 cvmx_pko_doorbell_pkoid(pko_port, queue, 3);
204 return CVMX_PKO_SUCCESS;
205 } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY) ||
206 (result == CVMX_CMD_QUEUE_FULL)) {
207 return CVMX_PKO_NO_MEMORY;
208 } else {
209 return CVMX_PKO_INVALID_QUEUE;
210 }
211}
212
213#endif /* __CVMX_PKO_H__ */