1
2
3
4
5#include <ethdev_driver.h>
6#include <rte_cycles.h>
7
8#include "lio_logs.h"
9#include "lio_struct.h"
10#include "lio_mbox.h"
11
12
13
14
15
16
17
18
19int
20lio_mbox_read(struct lio_mbox *mbox)
21{
22 union lio_mbox_message msg;
23 int ret = 0;
24
25 msg.mbox_msg64 = rte_read64(mbox->mbox_read_reg);
26
27 if ((msg.mbox_msg64 == LIO_PFVFACK) || (msg.mbox_msg64 == LIO_PFVFSIG))
28 return 0;
29
30 if (mbox->state & LIO_MBOX_STATE_REQ_RECEIVING) {
31 mbox->mbox_req.data[mbox->mbox_req.recv_len - 1] =
32 msg.mbox_msg64;
33 mbox->mbox_req.recv_len++;
34 } else {
35 if (mbox->state & LIO_MBOX_STATE_RES_RECEIVING) {
36 mbox->mbox_resp.data[mbox->mbox_resp.recv_len - 1] =
37 msg.mbox_msg64;
38 mbox->mbox_resp.recv_len++;
39 } else {
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;
47 } else {
48 if ((mbox->state &
49 LIO_MBOX_STATE_RES_PENDING) &&
50 (msg.s.type == LIO_MBOX_RESPONSE)) {
51 mbox->state &=
52 ~LIO_MBOX_STATE_RES_PENDING;
53 mbox->state |=
54 LIO_MBOX_STATE_RES_RECEIVING;
55 mbox->mbox_resp.msg.mbox_msg64 =
56 msg.mbox_msg64;
57 mbox->mbox_resp.q_no = mbox->q_no;
58 mbox->mbox_resp.recv_len = 1;
59 } else {
60 rte_write64(LIO_PFVFERR,
61 mbox->mbox_read_reg);
62 mbox->state |= LIO_MBOX_STATE_ERROR;
63 return -1;
64 }
65 }
66 }
67 }
68
69 if (mbox->state & LIO_MBOX_STATE_REQ_RECEIVING) {
70 if (mbox->mbox_req.recv_len < msg.s.len) {
71 ret = 0;
72 } else {
73 mbox->state &= ~LIO_MBOX_STATE_REQ_RECEIVING;
74 mbox->state |= LIO_MBOX_STATE_REQ_RECEIVED;
75 ret = 1;
76 }
77 } else {
78 if (mbox->state & LIO_MBOX_STATE_RES_RECEIVING) {
79 if (mbox->mbox_resp.recv_len < msg.s.len) {
80 ret = 0;
81 } else {
82 mbox->state &= ~LIO_MBOX_STATE_RES_RECEIVING;
83 mbox->state |= LIO_MBOX_STATE_RES_RECEIVED;
84 ret = 1;
85 }
86 } else {
87 RTE_ASSERT(0);
88 }
89 }
90
91 rte_write64(LIO_PFVFACK, mbox->mbox_read_reg);
92
93 return ret;
94}
95
96
97
98
99
100
101
102
103
104
105int
106lio_mbox_write(struct lio_device *lio_dev,
107 struct lio_mbox_cmd *mbox_cmd)
108{
109 struct lio_mbox *mbox = lio_dev->mbox[mbox_cmd->q_no];
110 uint32_t count, i, ret = LIO_MBOX_STATUS_SUCCESS;
111
112 if ((mbox_cmd->msg.s.type == LIO_MBOX_RESPONSE) &&
113 !(mbox->state & LIO_MBOX_STATE_REQ_RECEIVED))
114 return LIO_MBOX_STATUS_FAILED;
115
116 if ((mbox_cmd->msg.s.type == LIO_MBOX_REQUEST) &&
117 !(mbox->state & LIO_MBOX_STATE_IDLE))
118 return LIO_MBOX_STATUS_BUSY;
119
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;
124 }
125
126 count = 0;
127
128 while (rte_read64(mbox->mbox_write_reg) != LIO_PFVFSIG) {
129 rte_delay_ms(1);
130 if (count++ == 1000) {
131 ret = LIO_MBOX_STATUS_FAILED;
132 break;
133 }
134 }
135
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++) {
139 count = 0;
140 while (rte_read64(mbox->mbox_write_reg) !=
141 LIO_PFVFACK) {
142 rte_delay_ms(1);
143 if (count++ == 1000) {
144 ret = LIO_MBOX_STATUS_FAILED;
145 break;
146 }
147 }
148 rte_write64(mbox_cmd->data[i], mbox->mbox_write_reg);
149 }
150 }
151
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);
155 } else {
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;
162 }
163 }
164
165 return ret;
166}
167
168
169
170
171
172
173
174
175static int
176lio_mbox_process_cmd(struct lio_mbox *mbox,
177 struct lio_mbox_cmd *mbox_cmd)
178{
179 struct lio_device *lio_dev = mbox->lio_dev;
180
181 if (mbox_cmd->msg.s.cmd == LIO_CORES_CRASHED)
182 lio_dev_err(lio_dev, "Octeon core(s) crashed or got stuck!\n");
183
184 return 0;
185}
186
187
188
189
190int
191lio_mbox_process_message(struct lio_mbox *mbox)
192{
193 struct lio_mbox_cmd mbox_cmd;
194
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;
203 if (mbox_cmd.fn)
204 mbox_cmd.fn(mbox->lio_dev, &mbox_cmd,
205 mbox_cmd.fn_arg);
206
207 return 0;
208 }
209
210 mbox->state = LIO_MBOX_STATE_IDLE;
211 rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
212
213 return 0;
214 }
215
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;
222 if (mbox_cmd.fn)
223 mbox_cmd.fn(mbox->lio_dev, &mbox_cmd, mbox_cmd.fn_arg);
224
225 return 0;
226 }
227
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);
236 }
237
238 lio_mbox_process_cmd(mbox, &mbox_cmd);
239
240 return 0;
241 }
242
243 RTE_ASSERT(0);
244
245 return 0;
246}
247