1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Cavium, Inc
5 #include <ethdev_driver.h>
6 #include <rte_cycles.h>
9 #include "lio_struct.h"
14 * @mbox: Pointer mailbox
16 * Reads the 8-bytes of data from the mbox register
17 * Writes back the acknowledgment indicating completion of read
20 lio_mbox_read(struct lio_mbox *mbox)
22 union lio_mbox_message msg;
25 msg.mbox_msg64 = rte_read64(mbox->mbox_read_reg);
27 if ((msg.mbox_msg64 == LIO_PFVFACK) || (msg.mbox_msg64 == LIO_PFVFSIG))
30 if (mbox->state & LIO_MBOX_STATE_REQ_RECEIVING) {
31 mbox->mbox_req.data[mbox->mbox_req.recv_len - 1] =
33 mbox->mbox_req.recv_len++;
35 if (mbox->state & LIO_MBOX_STATE_RES_RECEIVING) {
36 mbox->mbox_resp.data[mbox->mbox_resp.recv_len - 1] =
38 mbox->mbox_resp.recv_len++;
40 if ((mbox->state & LIO_MBOX_STATE_IDLE) &&
41 (msg.s.type == LIO_MBOX_REQUEST)) {
42 mbox->state &= ~LIO_MBOX_STATE_IDLE;
43 mbox->state |= LIO_MBOX_STATE_REQ_RECEIVING;
44 mbox->mbox_req.msg.mbox_msg64 = msg.mbox_msg64;
45 mbox->mbox_req.q_no = mbox->q_no;
46 mbox->mbox_req.recv_len = 1;
49 LIO_MBOX_STATE_RES_PENDING) &&
50 (msg.s.type == LIO_MBOX_RESPONSE)) {
52 ~LIO_MBOX_STATE_RES_PENDING;
54 LIO_MBOX_STATE_RES_RECEIVING;
55 mbox->mbox_resp.msg.mbox_msg64 =
57 mbox->mbox_resp.q_no = mbox->q_no;
58 mbox->mbox_resp.recv_len = 1;
60 rte_write64(LIO_PFVFERR,
62 mbox->state |= LIO_MBOX_STATE_ERROR;
69 if (mbox->state & LIO_MBOX_STATE_REQ_RECEIVING) {
70 if (mbox->mbox_req.recv_len < msg.s.len) {
73 mbox->state &= ~LIO_MBOX_STATE_REQ_RECEIVING;
74 mbox->state |= LIO_MBOX_STATE_REQ_RECEIVED;
78 if (mbox->state & LIO_MBOX_STATE_RES_RECEIVING) {
79 if (mbox->mbox_resp.recv_len < msg.s.len) {
82 mbox->state &= ~LIO_MBOX_STATE_RES_RECEIVING;
83 mbox->state |= LIO_MBOX_STATE_RES_RECEIVED;
91 rte_write64(LIO_PFVFACK, mbox->mbox_read_reg);
98 * @lio_dev: Pointer lio device
99 * @mbox_cmd: Cmd to send to mailbox.
101 * Populates the queue specific mbox structure
102 * with cmd information.
103 * Write the cmd to mbox register
106 lio_mbox_write(struct lio_device *lio_dev,
107 struct lio_mbox_cmd *mbox_cmd)
109 struct lio_mbox *mbox = lio_dev->mbox[mbox_cmd->q_no];
110 uint32_t count, i, ret = LIO_MBOX_STATUS_SUCCESS;
112 if ((mbox_cmd->msg.s.type == LIO_MBOX_RESPONSE) &&
113 !(mbox->state & LIO_MBOX_STATE_REQ_RECEIVED))
114 return LIO_MBOX_STATUS_FAILED;
116 if ((mbox_cmd->msg.s.type == LIO_MBOX_REQUEST) &&
117 !(mbox->state & LIO_MBOX_STATE_IDLE))
118 return LIO_MBOX_STATUS_BUSY;
120 if (mbox_cmd->msg.s.type == LIO_MBOX_REQUEST) {
121 rte_memcpy(&mbox->mbox_resp, mbox_cmd,
122 sizeof(struct lio_mbox_cmd));
123 mbox->state = LIO_MBOX_STATE_RES_PENDING;
128 while (rte_read64(mbox->mbox_write_reg) != LIO_PFVFSIG) {
130 if (count++ == 1000) {
131 ret = LIO_MBOX_STATUS_FAILED;
136 if (ret == LIO_MBOX_STATUS_SUCCESS) {
137 rte_write64(mbox_cmd->msg.mbox_msg64, mbox->mbox_write_reg);
138 for (i = 0; i < (uint32_t)(mbox_cmd->msg.s.len - 1); i++) {
140 while (rte_read64(mbox->mbox_write_reg) !=
143 if (count++ == 1000) {
144 ret = LIO_MBOX_STATUS_FAILED;
148 rte_write64(mbox_cmd->data[i], mbox->mbox_write_reg);
152 if (mbox_cmd->msg.s.type == LIO_MBOX_RESPONSE) {
153 mbox->state = LIO_MBOX_STATE_IDLE;
154 rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
156 if ((!mbox_cmd->msg.s.resp_needed) ||
157 (ret == LIO_MBOX_STATUS_FAILED)) {
158 mbox->state &= ~LIO_MBOX_STATE_RES_PENDING;
159 if (!(mbox->state & (LIO_MBOX_STATE_REQ_RECEIVING |
160 LIO_MBOX_STATE_REQ_RECEIVED)))
161 mbox->state = LIO_MBOX_STATE_IDLE;
169 * lio_mbox_process_cmd:
170 * @mbox: Pointer mailbox
171 * @mbox_cmd: Pointer to command received
173 * Process the cmd received in mbox
176 lio_mbox_process_cmd(struct lio_mbox *mbox,
177 struct lio_mbox_cmd *mbox_cmd)
179 struct lio_device *lio_dev = mbox->lio_dev;
181 if (mbox_cmd->msg.s.cmd == LIO_CORES_CRASHED)
182 lio_dev_err(lio_dev, "Octeon core(s) crashed or got stuck!\n");
188 * Process the received mbox message.
191 lio_mbox_process_message(struct lio_mbox *mbox)
193 struct lio_mbox_cmd mbox_cmd;
195 if (mbox->state & LIO_MBOX_STATE_ERROR) {
196 if (mbox->state & (LIO_MBOX_STATE_RES_PENDING |
197 LIO_MBOX_STATE_RES_RECEIVING)) {
198 rte_memcpy(&mbox_cmd, &mbox->mbox_resp,
199 sizeof(struct lio_mbox_cmd));
200 mbox->state = LIO_MBOX_STATE_IDLE;
201 rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
202 mbox_cmd.recv_status = 1;
204 mbox_cmd.fn(mbox->lio_dev, &mbox_cmd,
210 mbox->state = LIO_MBOX_STATE_IDLE;
211 rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
216 if (mbox->state & LIO_MBOX_STATE_RES_RECEIVED) {
217 rte_memcpy(&mbox_cmd, &mbox->mbox_resp,
218 sizeof(struct lio_mbox_cmd));
219 mbox->state = LIO_MBOX_STATE_IDLE;
220 rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
221 mbox_cmd.recv_status = 0;
223 mbox_cmd.fn(mbox->lio_dev, &mbox_cmd, mbox_cmd.fn_arg);
228 if (mbox->state & LIO_MBOX_STATE_REQ_RECEIVED) {
229 rte_memcpy(&mbox_cmd, &mbox->mbox_req,
230 sizeof(struct lio_mbox_cmd));
231 if (!mbox_cmd.msg.s.resp_needed) {
232 mbox->state &= ~LIO_MBOX_STATE_REQ_RECEIVED;
233 if (!(mbox->state & LIO_MBOX_STATE_RES_PENDING))
234 mbox->state = LIO_MBOX_STATE_IDLE;
235 rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
238 lio_mbox_process_cmd(mbox, &mbox_cmd);