1/* 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__ */ 214