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);