1 /**********************************************************************
4 * Contact: support@cavium.com
5 * Please include "LiquidIO" in the subject.
7 * Copyright (c) 2003-2016 Cavium, Inc.
9 * This file is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License, Version 2, as
11 * published by the Free Software Foundation.
13 * This file is distributed in the hope that it will be useful, but
14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16 * NONINFRINGEMENT. See the GNU General Public License for more details.
17 ***********************************************************************/
18 #include <linux/pci.h>
19 #include <linux/netdevice.h>
20 #include "liquidio_common.h"
21 #include "octeon_droq.h"
22 #include "octeon_iq.h"
23 #include "response_manager.h"
24 #include "octeon_device.h"
25 #include "octeon_main.h"
26 #include "octeon_mailbox.h"
27 #include "cn23xx_pf_device.h"
31 * @oct: Pointer mailbox
33 * Reads the 8-bytes of data from the mbox register
34 * Writes back the acknowldgement inidcating completion of read
36 int octeon_mbox_read(struct octeon_mbox
*mbox
)
38 union octeon_mbox_message msg
;
41 spin_lock(&mbox
->lock
);
43 msg
.u64
= readq(mbox
->mbox_read_reg
);
45 if ((msg
.u64
== OCTEON_PFVFACK
) || (msg
.u64
== OCTEON_PFVFSIG
)) {
46 spin_unlock(&mbox
->lock
);
50 if (mbox
->state
& OCTEON_MBOX_STATE_REQUEST_RECEIVING
) {
51 mbox
->mbox_req
.data
[mbox
->mbox_req
.recv_len
- 1] = msg
.u64
;
52 mbox
->mbox_req
.recv_len
++;
54 if (mbox
->state
& OCTEON_MBOX_STATE_RESPONSE_RECEIVING
) {
55 mbox
->mbox_resp
.data
[mbox
->mbox_resp
.recv_len
- 1] =
57 mbox
->mbox_resp
.recv_len
++;
59 if ((mbox
->state
& OCTEON_MBOX_STATE_IDLE
) &&
60 (msg
.s
.type
== OCTEON_MBOX_REQUEST
)) {
61 mbox
->state
&= ~OCTEON_MBOX_STATE_IDLE
;
63 OCTEON_MBOX_STATE_REQUEST_RECEIVING
;
64 mbox
->mbox_req
.msg
.u64
= msg
.u64
;
65 mbox
->mbox_req
.q_no
= mbox
->q_no
;
66 mbox
->mbox_req
.recv_len
= 1;
69 OCTEON_MBOX_STATE_RESPONSE_PENDING
) &&
70 (msg
.s
.type
== OCTEON_MBOX_RESPONSE
)) {
72 ~OCTEON_MBOX_STATE_RESPONSE_PENDING
;
74 OCTEON_MBOX_STATE_RESPONSE_RECEIVING
76 mbox
->mbox_resp
.msg
.u64
= msg
.u64
;
77 mbox
->mbox_resp
.q_no
= mbox
->q_no
;
78 mbox
->mbox_resp
.recv_len
= 1;
80 writeq(OCTEON_PFVFERR
,
82 mbox
->state
|= OCTEON_MBOX_STATE_ERROR
;
83 spin_unlock(&mbox
->lock
);
90 if (mbox
->state
& OCTEON_MBOX_STATE_REQUEST_RECEIVING
) {
91 if (mbox
->mbox_req
.recv_len
< mbox
->mbox_req
.msg
.s
.len
) {
94 mbox
->state
&= ~OCTEON_MBOX_STATE_REQUEST_RECEIVING
;
95 mbox
->state
|= OCTEON_MBOX_STATE_REQUEST_RECEIVED
;
99 if (mbox
->state
& OCTEON_MBOX_STATE_RESPONSE_RECEIVING
) {
100 if (mbox
->mbox_resp
.recv_len
<
101 mbox
->mbox_resp
.msg
.s
.len
) {
105 ~OCTEON_MBOX_STATE_RESPONSE_RECEIVING
;
107 OCTEON_MBOX_STATE_RESPONSE_RECEIVED
;
115 writeq(OCTEON_PFVFACK
, mbox
->mbox_read_reg
);
117 spin_unlock(&mbox
->lock
);
124 * @oct: Pointer Octeon Device
125 * @mbox_cmd: Cmd to send to mailbox.
127 * Populates the queue specific mbox structure
128 * with cmd information.
129 * Write the cmd to mbox register
131 int octeon_mbox_write(struct octeon_device
*oct
,
132 struct octeon_mbox_cmd
*mbox_cmd
)
134 struct octeon_mbox
*mbox
= oct
->mbox
[mbox_cmd
->q_no
];
135 u32 count
, i
, ret
= OCTEON_MBOX_STATUS_SUCCESS
;
136 long timeout
= LIO_MBOX_WRITE_WAIT_TIME
;
139 spin_lock_irqsave(&mbox
->lock
, flags
);
141 if ((mbox_cmd
->msg
.s
.type
== OCTEON_MBOX_RESPONSE
) &&
142 !(mbox
->state
& OCTEON_MBOX_STATE_REQUEST_RECEIVED
)) {
143 spin_unlock_irqrestore(&mbox
->lock
, flags
);
144 return OCTEON_MBOX_STATUS_FAILED
;
147 if ((mbox_cmd
->msg
.s
.type
== OCTEON_MBOX_REQUEST
) &&
148 !(mbox
->state
& OCTEON_MBOX_STATE_IDLE
)) {
149 spin_unlock_irqrestore(&mbox
->lock
, flags
);
150 return OCTEON_MBOX_STATUS_BUSY
;
153 if (mbox_cmd
->msg
.s
.type
== OCTEON_MBOX_REQUEST
) {
154 memcpy(&mbox
->mbox_resp
, mbox_cmd
,
155 sizeof(struct octeon_mbox_cmd
));
156 mbox
->state
= OCTEON_MBOX_STATE_RESPONSE_PENDING
;
159 spin_unlock_irqrestore(&mbox
->lock
, flags
);
163 while (readq(mbox
->mbox_write_reg
) != OCTEON_PFVFSIG
) {
164 schedule_timeout_uninterruptible(timeout
);
165 if (count
++ == LIO_MBOX_WRITE_WAIT_CNT
) {
166 ret
= OCTEON_MBOX_STATUS_FAILED
;
171 if (ret
== OCTEON_MBOX_STATUS_SUCCESS
) {
172 writeq(mbox_cmd
->msg
.u64
, mbox
->mbox_write_reg
);
173 for (i
= 0; i
< (u32
)(mbox_cmd
->msg
.s
.len
- 1); i
++) {
175 while (readq(mbox
->mbox_write_reg
) !=
177 schedule_timeout_uninterruptible(timeout
);
178 if (count
++ == LIO_MBOX_WRITE_WAIT_CNT
) {
179 ret
= OCTEON_MBOX_STATUS_FAILED
;
183 if (ret
== OCTEON_MBOX_STATUS_SUCCESS
)
184 writeq(mbox_cmd
->data
[i
], mbox
->mbox_write_reg
);
190 spin_lock_irqsave(&mbox
->lock
, flags
);
191 if (mbox_cmd
->msg
.s
.type
== OCTEON_MBOX_RESPONSE
) {
192 mbox
->state
= OCTEON_MBOX_STATE_IDLE
;
193 writeq(OCTEON_PFVFSIG
, mbox
->mbox_read_reg
);
195 if ((!mbox_cmd
->msg
.s
.resp_needed
) ||
196 (ret
== OCTEON_MBOX_STATUS_FAILED
)) {
197 mbox
->state
&= ~OCTEON_MBOX_STATE_RESPONSE_PENDING
;
199 (OCTEON_MBOX_STATE_REQUEST_RECEIVING
|
200 OCTEON_MBOX_STATE_REQUEST_RECEIVED
)))
201 mbox
->state
= OCTEON_MBOX_STATE_IDLE
;
204 spin_unlock_irqrestore(&mbox
->lock
, flags
);
209 static void get_vf_stats(struct octeon_device
*oct
,
210 struct oct_vf_stats
*stats
)
214 for (i
= 0; i
< oct
->num_iqs
; i
++) {
215 if (!oct
->instr_queue
[i
])
217 stats
->tx_packets
+= oct
->instr_queue
[i
]->stats
.tx_done
;
218 stats
->tx_bytes
+= oct
->instr_queue
[i
]->stats
.tx_tot_bytes
;
221 for (i
= 0; i
< oct
->num_oqs
; i
++) {
224 stats
->rx_packets
+= oct
->droq
[i
]->stats
.rx_pkts_received
;
225 stats
->rx_bytes
+= oct
->droq
[i
]->stats
.rx_bytes_received
;
230 * octeon_mbox_process_cmd:
231 * @mbox: Pointer mailbox
232 * @mbox_cmd: Pointer to command received
234 * Process the cmd received in mbox
236 static int octeon_mbox_process_cmd(struct octeon_mbox
*mbox
,
237 struct octeon_mbox_cmd
*mbox_cmd
)
239 struct octeon_device
*oct
= mbox
->oct_dev
;
241 switch (mbox_cmd
->msg
.s
.cmd
) {
242 case OCTEON_VF_ACTIVE
:
243 dev_dbg(&oct
->pci_dev
->dev
, "got vfactive sending data back\n");
244 mbox_cmd
->msg
.s
.type
= OCTEON_MBOX_RESPONSE
;
245 mbox_cmd
->msg
.s
.resp_needed
= 1;
246 mbox_cmd
->msg
.s
.len
= 2;
247 mbox_cmd
->data
[0] = 0; /* VF version is in mbox_cmd->data[0] */
248 ((struct lio_version
*)&mbox_cmd
->data
[0])->major
=
249 LIQUIDIO_BASE_MAJOR_VERSION
;
250 ((struct lio_version
*)&mbox_cmd
->data
[0])->minor
=
251 LIQUIDIO_BASE_MINOR_VERSION
;
252 ((struct lio_version
*)&mbox_cmd
->data
[0])->micro
=
253 LIQUIDIO_BASE_MICRO_VERSION
;
254 memcpy(mbox_cmd
->msg
.s
.params
, (uint8_t *)&oct
->pfvf_hsword
, 6);
255 /* Sending core cofig info to the corresponding active VF.*/
256 octeon_mbox_write(oct
, mbox_cmd
);
259 case OCTEON_VF_FLR_REQUEST
:
260 dev_info(&oct
->pci_dev
->dev
,
261 "got a request for FLR from VF that owns DPI ring %u\n",
263 pcie_flr(oct
->sriov_info
.dpiring_to_vfpcidev_lut
[mbox
->q_no
]);
266 case OCTEON_PF_CHANGED_VF_MACADDR
:
267 if (OCTEON_CN23XX_VF(oct
))
268 octeon_pf_changed_vf_macaddr(oct
,
269 mbox_cmd
->msg
.s
.params
);
272 case OCTEON_GET_VF_STATS
:
273 dev_dbg(&oct
->pci_dev
->dev
, "Got VF stats request. Sending data back\n");
274 mbox_cmd
->msg
.s
.type
= OCTEON_MBOX_RESPONSE
;
275 mbox_cmd
->msg
.s
.resp_needed
= 1;
276 mbox_cmd
->msg
.s
.len
= 1 +
277 sizeof(struct oct_vf_stats
) / sizeof(u64
);
278 get_vf_stats(oct
, (struct oct_vf_stats
*)mbox_cmd
->data
);
279 octeon_mbox_write(oct
, mbox_cmd
);
288 *octeon_mbox_process_message:
290 * Process the received mbox message.
292 int octeon_mbox_process_message(struct octeon_mbox
*mbox
)
294 struct octeon_mbox_cmd mbox_cmd
;
297 spin_lock_irqsave(&mbox
->lock
, flags
);
299 if (mbox
->state
& OCTEON_MBOX_STATE_ERROR
) {
300 if (mbox
->state
& (OCTEON_MBOX_STATE_RESPONSE_PENDING
|
301 OCTEON_MBOX_STATE_RESPONSE_RECEIVING
)) {
302 memcpy(&mbox_cmd
, &mbox
->mbox_resp
,
303 sizeof(struct octeon_mbox_cmd
));
304 mbox
->state
= OCTEON_MBOX_STATE_IDLE
;
305 writeq(OCTEON_PFVFSIG
, mbox
->mbox_read_reg
);
306 spin_unlock_irqrestore(&mbox
->lock
, flags
);
307 mbox_cmd
.recv_status
= 1;
309 mbox_cmd
.fn(mbox
->oct_dev
, &mbox_cmd
,
314 mbox
->state
= OCTEON_MBOX_STATE_IDLE
;
315 writeq(OCTEON_PFVFSIG
, mbox
->mbox_read_reg
);
316 spin_unlock_irqrestore(&mbox
->lock
, flags
);
320 if (mbox
->state
& OCTEON_MBOX_STATE_RESPONSE_RECEIVED
) {
321 memcpy(&mbox_cmd
, &mbox
->mbox_resp
,
322 sizeof(struct octeon_mbox_cmd
));
323 mbox
->state
= OCTEON_MBOX_STATE_IDLE
;
324 writeq(OCTEON_PFVFSIG
, mbox
->mbox_read_reg
);
325 spin_unlock_irqrestore(&mbox
->lock
, flags
);
326 mbox_cmd
.recv_status
= 0;
328 mbox_cmd
.fn(mbox
->oct_dev
, &mbox_cmd
, mbox_cmd
.fn_arg
);
332 if (mbox
->state
& OCTEON_MBOX_STATE_REQUEST_RECEIVED
) {
333 memcpy(&mbox_cmd
, &mbox
->mbox_req
,
334 sizeof(struct octeon_mbox_cmd
));
335 if (!mbox_cmd
.msg
.s
.resp_needed
) {
336 mbox
->state
&= ~OCTEON_MBOX_STATE_REQUEST_RECEIVED
;
338 OCTEON_MBOX_STATE_RESPONSE_PENDING
))
339 mbox
->state
= OCTEON_MBOX_STATE_IDLE
;
340 writeq(OCTEON_PFVFSIG
, mbox
->mbox_read_reg
);
343 spin_unlock_irqrestore(&mbox
->lock
, flags
);
344 octeon_mbox_process_cmd(mbox
, &mbox_cmd
);
348 spin_unlock_irqrestore(&mbox
->lock
, flags
);
354 int octeon_mbox_cancel(struct octeon_device
*oct
, int q_no
)
356 struct octeon_mbox
*mbox
= oct
->mbox
[q_no
];
357 struct octeon_mbox_cmd
*mbox_cmd
;
358 unsigned long flags
= 0;
360 spin_lock_irqsave(&mbox
->lock
, flags
);
361 mbox_cmd
= &mbox
->mbox_resp
;
363 if (!(mbox
->state
& OCTEON_MBOX_STATE_RESPONSE_PENDING
)) {
364 spin_unlock_irqrestore(&mbox
->lock
, flags
);
368 mbox
->state
= OCTEON_MBOX_STATE_IDLE
;
369 memset(mbox_cmd
, 0, sizeof(*mbox_cmd
));
370 writeq(OCTEON_PFVFSIG
, mbox
->mbox_read_reg
);
371 spin_unlock_irqrestore(&mbox
->lock
, flags
);