4 * Copyright(c) 2017 Cavium, Inc.. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
34 #include <rte_ethdev.h>
35 #include <rte_cycles.h>
38 #include "lio_struct.h"
43 * @mbox: Pointer mailbox
45 * Reads the 8-bytes of data from the mbox register
46 * Writes back the acknowledgment indicating completion of read
49 lio_mbox_read(struct lio_mbox
*mbox
)
51 union lio_mbox_message msg
;
54 msg
.mbox_msg64
= rte_read64(mbox
->mbox_read_reg
);
56 if ((msg
.mbox_msg64
== LIO_PFVFACK
) || (msg
.mbox_msg64
== LIO_PFVFSIG
))
59 if (mbox
->state
& LIO_MBOX_STATE_REQ_RECEIVING
) {
60 mbox
->mbox_req
.data
[mbox
->mbox_req
.recv_len
- 1] =
62 mbox
->mbox_req
.recv_len
++;
64 if (mbox
->state
& LIO_MBOX_STATE_RES_RECEIVING
) {
65 mbox
->mbox_resp
.data
[mbox
->mbox_resp
.recv_len
- 1] =
67 mbox
->mbox_resp
.recv_len
++;
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;
78 LIO_MBOX_STATE_RES_PENDING
) &&
79 (msg
.s
.type
== LIO_MBOX_RESPONSE
)) {
81 ~LIO_MBOX_STATE_RES_PENDING
;
83 LIO_MBOX_STATE_RES_RECEIVING
;
84 mbox
->mbox_resp
.msg
.mbox_msg64
=
86 mbox
->mbox_resp
.q_no
= mbox
->q_no
;
87 mbox
->mbox_resp
.recv_len
= 1;
89 rte_write64(LIO_PFVFERR
,
91 mbox
->state
|= LIO_MBOX_STATE_ERROR
;
98 if (mbox
->state
& LIO_MBOX_STATE_REQ_RECEIVING
) {
99 if (mbox
->mbox_req
.recv_len
< msg
.s
.len
) {
102 mbox
->state
&= ~LIO_MBOX_STATE_REQ_RECEIVING
;
103 mbox
->state
|= LIO_MBOX_STATE_REQ_RECEIVED
;
107 if (mbox
->state
& LIO_MBOX_STATE_RES_RECEIVING
) {
108 if (mbox
->mbox_resp
.recv_len
< msg
.s
.len
) {
111 mbox
->state
&= ~LIO_MBOX_STATE_RES_RECEIVING
;
112 mbox
->state
|= LIO_MBOX_STATE_RES_RECEIVED
;
120 rte_write64(LIO_PFVFACK
, mbox
->mbox_read_reg
);
127 * @lio_dev: Pointer lio device
128 * @mbox_cmd: Cmd to send to mailbox.
130 * Populates the queue specific mbox structure
131 * with cmd information.
132 * Write the cmd to mbox register
135 lio_mbox_write(struct lio_device
*lio_dev
,
136 struct lio_mbox_cmd
*mbox_cmd
)
138 struct lio_mbox
*mbox
= lio_dev
->mbox
[mbox_cmd
->q_no
];
139 uint32_t count
, i
, ret
= LIO_MBOX_STATUS_SUCCESS
;
141 if ((mbox_cmd
->msg
.s
.type
== LIO_MBOX_RESPONSE
) &&
142 !(mbox
->state
& LIO_MBOX_STATE_REQ_RECEIVED
))
143 return LIO_MBOX_STATUS_FAILED
;
145 if ((mbox_cmd
->msg
.s
.type
== LIO_MBOX_REQUEST
) &&
146 !(mbox
->state
& LIO_MBOX_STATE_IDLE
))
147 return LIO_MBOX_STATUS_BUSY
;
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
;
157 while (rte_read64(mbox
->mbox_write_reg
) != LIO_PFVFSIG
) {
159 if (count
++ == 1000) {
160 ret
= LIO_MBOX_STATUS_FAILED
;
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
++) {
169 while (rte_read64(mbox
->mbox_write_reg
) !=
172 if (count
++ == 1000) {
173 ret
= LIO_MBOX_STATUS_FAILED
;
177 rte_write64(mbox_cmd
->data
[i
], mbox
->mbox_write_reg
);
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
);
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
;
198 * lio_mbox_process_cmd:
199 * @mbox: Pointer mailbox
200 * @mbox_cmd: Pointer to command received
202 * Process the cmd received in mbox
205 lio_mbox_process_cmd(struct lio_mbox
*mbox
,
206 struct lio_mbox_cmd
*mbox_cmd
)
208 struct lio_device
*lio_dev
= mbox
->lio_dev
;
210 if (mbox_cmd
->msg
.s
.cmd
== LIO_CORES_CRASHED
)
211 lio_dev_err(lio_dev
, "Octeon core(s) crashed or got stuck!\n");
217 * Process the received mbox message.
220 lio_mbox_process_message(struct lio_mbox
*mbox
)
222 struct lio_mbox_cmd mbox_cmd
;
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;
233 mbox_cmd
.fn(mbox
->lio_dev
, &mbox_cmd
,
239 mbox
->state
= LIO_MBOX_STATE_IDLE
;
240 rte_write64(LIO_PFVFSIG
, mbox
->mbox_read_reg
);
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;
252 mbox_cmd
.fn(mbox
->lio_dev
, &mbox_cmd
, mbox_cmd
.fn_arg
);
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
);
267 lio_mbox_process_cmd(mbox
, &mbox_cmd
);