]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/dpdk/drivers/net/liquidio/base/lio_mbox.c
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / seastar / dpdk / drivers / net / liquidio / base / lio_mbox.c
1 /*
2 * BSD LICENSE
3 *
4 * Copyright(c) 2017 Cavium, Inc.. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Cavium, Inc. nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <rte_ethdev.h>
35 #include <rte_cycles.h>
36
37 #include "lio_logs.h"
38 #include "lio_struct.h"
39 #include "lio_mbox.h"
40
41 /**
42 * lio_mbox_read:
43 * @mbox: Pointer mailbox
44 *
45 * Reads the 8-bytes of data from the mbox register
46 * Writes back the acknowledgment indicating completion of read
47 */
48 int
49 lio_mbox_read(struct lio_mbox *mbox)
50 {
51 union lio_mbox_message msg;
52 int ret = 0;
53
54 msg.mbox_msg64 = rte_read64(mbox->mbox_read_reg);
55
56 if ((msg.mbox_msg64 == LIO_PFVFACK) || (msg.mbox_msg64 == LIO_PFVFSIG))
57 return 0;
58
59 if (mbox->state & LIO_MBOX_STATE_REQ_RECEIVING) {
60 mbox->mbox_req.data[mbox->mbox_req.recv_len - 1] =
61 msg.mbox_msg64;
62 mbox->mbox_req.recv_len++;
63 } else {
64 if (mbox->state & LIO_MBOX_STATE_RES_RECEIVING) {
65 mbox->mbox_resp.data[mbox->mbox_resp.recv_len - 1] =
66 msg.mbox_msg64;
67 mbox->mbox_resp.recv_len++;
68 } else {
69 if ((mbox->state & LIO_MBOX_STATE_IDLE) &&
70 (msg.s.type == LIO_MBOX_REQUEST)) {
71 mbox->state &= ~LIO_MBOX_STATE_IDLE;
72 mbox->state |= LIO_MBOX_STATE_REQ_RECEIVING;
73 mbox->mbox_req.msg.mbox_msg64 = msg.mbox_msg64;
74 mbox->mbox_req.q_no = mbox->q_no;
75 mbox->mbox_req.recv_len = 1;
76 } else {
77 if ((mbox->state &
78 LIO_MBOX_STATE_RES_PENDING) &&
79 (msg.s.type == LIO_MBOX_RESPONSE)) {
80 mbox->state &=
81 ~LIO_MBOX_STATE_RES_PENDING;
82 mbox->state |=
83 LIO_MBOX_STATE_RES_RECEIVING;
84 mbox->mbox_resp.msg.mbox_msg64 =
85 msg.mbox_msg64;
86 mbox->mbox_resp.q_no = mbox->q_no;
87 mbox->mbox_resp.recv_len = 1;
88 } else {
89 rte_write64(LIO_PFVFERR,
90 mbox->mbox_read_reg);
91 mbox->state |= LIO_MBOX_STATE_ERROR;
92 return -1;
93 }
94 }
95 }
96 }
97
98 if (mbox->state & LIO_MBOX_STATE_REQ_RECEIVING) {
99 if (mbox->mbox_req.recv_len < msg.s.len) {
100 ret = 0;
101 } else {
102 mbox->state &= ~LIO_MBOX_STATE_REQ_RECEIVING;
103 mbox->state |= LIO_MBOX_STATE_REQ_RECEIVED;
104 ret = 1;
105 }
106 } else {
107 if (mbox->state & LIO_MBOX_STATE_RES_RECEIVING) {
108 if (mbox->mbox_resp.recv_len < msg.s.len) {
109 ret = 0;
110 } else {
111 mbox->state &= ~LIO_MBOX_STATE_RES_RECEIVING;
112 mbox->state |= LIO_MBOX_STATE_RES_RECEIVED;
113 ret = 1;
114 }
115 } else {
116 RTE_ASSERT(0);
117 }
118 }
119
120 rte_write64(LIO_PFVFACK, mbox->mbox_read_reg);
121
122 return ret;
123 }
124
125 /**
126 * lio_mbox_write:
127 * @lio_dev: Pointer lio device
128 * @mbox_cmd: Cmd to send to mailbox.
129 *
130 * Populates the queue specific mbox structure
131 * with cmd information.
132 * Write the cmd to mbox register
133 */
134 int
135 lio_mbox_write(struct lio_device *lio_dev,
136 struct lio_mbox_cmd *mbox_cmd)
137 {
138 struct lio_mbox *mbox = lio_dev->mbox[mbox_cmd->q_no];
139 uint32_t count, i, ret = LIO_MBOX_STATUS_SUCCESS;
140
141 if ((mbox_cmd->msg.s.type == LIO_MBOX_RESPONSE) &&
142 !(mbox->state & LIO_MBOX_STATE_REQ_RECEIVED))
143 return LIO_MBOX_STATUS_FAILED;
144
145 if ((mbox_cmd->msg.s.type == LIO_MBOX_REQUEST) &&
146 !(mbox->state & LIO_MBOX_STATE_IDLE))
147 return LIO_MBOX_STATUS_BUSY;
148
149 if (mbox_cmd->msg.s.type == LIO_MBOX_REQUEST) {
150 rte_memcpy(&mbox->mbox_resp, mbox_cmd,
151 sizeof(struct lio_mbox_cmd));
152 mbox->state = LIO_MBOX_STATE_RES_PENDING;
153 }
154
155 count = 0;
156
157 while (rte_read64(mbox->mbox_write_reg) != LIO_PFVFSIG) {
158 rte_delay_ms(1);
159 if (count++ == 1000) {
160 ret = LIO_MBOX_STATUS_FAILED;
161 break;
162 }
163 }
164
165 if (ret == LIO_MBOX_STATUS_SUCCESS) {
166 rte_write64(mbox_cmd->msg.mbox_msg64, mbox->mbox_write_reg);
167 for (i = 0; i < (uint32_t)(mbox_cmd->msg.s.len - 1); i++) {
168 count = 0;
169 while (rte_read64(mbox->mbox_write_reg) !=
170 LIO_PFVFACK) {
171 rte_delay_ms(1);
172 if (count++ == 1000) {
173 ret = LIO_MBOX_STATUS_FAILED;
174 break;
175 }
176 }
177 rte_write64(mbox_cmd->data[i], mbox->mbox_write_reg);
178 }
179 }
180
181 if (mbox_cmd->msg.s.type == LIO_MBOX_RESPONSE) {
182 mbox->state = LIO_MBOX_STATE_IDLE;
183 rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
184 } else {
185 if ((!mbox_cmd->msg.s.resp_needed) ||
186 (ret == LIO_MBOX_STATUS_FAILED)) {
187 mbox->state &= ~LIO_MBOX_STATE_RES_PENDING;
188 if (!(mbox->state & (LIO_MBOX_STATE_REQ_RECEIVING |
189 LIO_MBOX_STATE_REQ_RECEIVED)))
190 mbox->state = LIO_MBOX_STATE_IDLE;
191 }
192 }
193
194 return ret;
195 }
196
197 /**
198 * lio_mbox_process_cmd:
199 * @mbox: Pointer mailbox
200 * @mbox_cmd: Pointer to command received
201 *
202 * Process the cmd received in mbox
203 */
204 static int
205 lio_mbox_process_cmd(struct lio_mbox *mbox,
206 struct lio_mbox_cmd *mbox_cmd)
207 {
208 struct lio_device *lio_dev = mbox->lio_dev;
209
210 if (mbox_cmd->msg.s.cmd == LIO_CORES_CRASHED)
211 lio_dev_err(lio_dev, "Octeon core(s) crashed or got stuck!\n");
212
213 return 0;
214 }
215
216 /**
217 * Process the received mbox message.
218 */
219 int
220 lio_mbox_process_message(struct lio_mbox *mbox)
221 {
222 struct lio_mbox_cmd mbox_cmd;
223
224 if (mbox->state & LIO_MBOX_STATE_ERROR) {
225 if (mbox->state & (LIO_MBOX_STATE_RES_PENDING |
226 LIO_MBOX_STATE_RES_RECEIVING)) {
227 rte_memcpy(&mbox_cmd, &mbox->mbox_resp,
228 sizeof(struct lio_mbox_cmd));
229 mbox->state = LIO_MBOX_STATE_IDLE;
230 rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
231 mbox_cmd.recv_status = 1;
232 if (mbox_cmd.fn)
233 mbox_cmd.fn(mbox->lio_dev, &mbox_cmd,
234 mbox_cmd.fn_arg);
235
236 return 0;
237 }
238
239 mbox->state = LIO_MBOX_STATE_IDLE;
240 rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
241
242 return 0;
243 }
244
245 if (mbox->state & LIO_MBOX_STATE_RES_RECEIVED) {
246 rte_memcpy(&mbox_cmd, &mbox->mbox_resp,
247 sizeof(struct lio_mbox_cmd));
248 mbox->state = LIO_MBOX_STATE_IDLE;
249 rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
250 mbox_cmd.recv_status = 0;
251 if (mbox_cmd.fn)
252 mbox_cmd.fn(mbox->lio_dev, &mbox_cmd, mbox_cmd.fn_arg);
253
254 return 0;
255 }
256
257 if (mbox->state & LIO_MBOX_STATE_REQ_RECEIVED) {
258 rte_memcpy(&mbox_cmd, &mbox->mbox_req,
259 sizeof(struct lio_mbox_cmd));
260 if (!mbox_cmd.msg.s.resp_needed) {
261 mbox->state &= ~LIO_MBOX_STATE_REQ_RECEIVED;
262 if (!(mbox->state & LIO_MBOX_STATE_RES_PENDING))
263 mbox->state = LIO_MBOX_STATE_IDLE;
264 rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
265 }
266
267 lio_mbox_process_cmd(mbox, &mbox_cmd);
268
269 return 0;
270 }
271
272 RTE_ASSERT(0);
273
274 return 0;
275 }