numam-dpdk/drivers/net/liquidio/base/lio_mbox.c
Ferruh Yigit ffc905f3b8 ethdev: separate driver APIs
Create a rte_ethdev_driver.h file and move PMD specific APIs here.
Drivers updated to include this new header file.

There is no update in header content and since ethdev.h included by
ethdev_driver.h, nothing changed from driver point of view, only
logically grouping of APIs. From applications point of view they can't
access to driver specific APIs anymore and they shouldn't.

More PMD specific data structures still remain in ethdev.h because of
inline functions in header use them. Those will be handled separately.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
2018-01-22 01:26:49 +01:00

247 lines
5.9 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2017 Cavium, Inc
*/
#include <rte_ethdev_driver.h>
#include <rte_cycles.h>
#include "lio_logs.h"
#include "lio_struct.h"
#include "lio_mbox.h"
/**
* lio_mbox_read:
* @mbox: Pointer mailbox
*
* Reads the 8-bytes of data from the mbox register
* Writes back the acknowledgment indicating completion of read
*/
int
lio_mbox_read(struct lio_mbox *mbox)
{
union lio_mbox_message msg;
int ret = 0;
msg.mbox_msg64 = rte_read64(mbox->mbox_read_reg);
if ((msg.mbox_msg64 == LIO_PFVFACK) || (msg.mbox_msg64 == LIO_PFVFSIG))
return 0;
if (mbox->state & LIO_MBOX_STATE_REQ_RECEIVING) {
mbox->mbox_req.data[mbox->mbox_req.recv_len - 1] =
msg.mbox_msg64;
mbox->mbox_req.recv_len++;
} else {
if (mbox->state & LIO_MBOX_STATE_RES_RECEIVING) {
mbox->mbox_resp.data[mbox->mbox_resp.recv_len - 1] =
msg.mbox_msg64;
mbox->mbox_resp.recv_len++;
} else {
if ((mbox->state & LIO_MBOX_STATE_IDLE) &&
(msg.s.type == LIO_MBOX_REQUEST)) {
mbox->state &= ~LIO_MBOX_STATE_IDLE;
mbox->state |= LIO_MBOX_STATE_REQ_RECEIVING;
mbox->mbox_req.msg.mbox_msg64 = msg.mbox_msg64;
mbox->mbox_req.q_no = mbox->q_no;
mbox->mbox_req.recv_len = 1;
} else {
if ((mbox->state &
LIO_MBOX_STATE_RES_PENDING) &&
(msg.s.type == LIO_MBOX_RESPONSE)) {
mbox->state &=
~LIO_MBOX_STATE_RES_PENDING;
mbox->state |=
LIO_MBOX_STATE_RES_RECEIVING;
mbox->mbox_resp.msg.mbox_msg64 =
msg.mbox_msg64;
mbox->mbox_resp.q_no = mbox->q_no;
mbox->mbox_resp.recv_len = 1;
} else {
rte_write64(LIO_PFVFERR,
mbox->mbox_read_reg);
mbox->state |= LIO_MBOX_STATE_ERROR;
return -1;
}
}
}
}
if (mbox->state & LIO_MBOX_STATE_REQ_RECEIVING) {
if (mbox->mbox_req.recv_len < msg.s.len) {
ret = 0;
} else {
mbox->state &= ~LIO_MBOX_STATE_REQ_RECEIVING;
mbox->state |= LIO_MBOX_STATE_REQ_RECEIVED;
ret = 1;
}
} else {
if (mbox->state & LIO_MBOX_STATE_RES_RECEIVING) {
if (mbox->mbox_resp.recv_len < msg.s.len) {
ret = 0;
} else {
mbox->state &= ~LIO_MBOX_STATE_RES_RECEIVING;
mbox->state |= LIO_MBOX_STATE_RES_RECEIVED;
ret = 1;
}
} else {
RTE_ASSERT(0);
}
}
rte_write64(LIO_PFVFACK, mbox->mbox_read_reg);
return ret;
}
/**
* lio_mbox_write:
* @lio_dev: Pointer lio device
* @mbox_cmd: Cmd to send to mailbox.
*
* Populates the queue specific mbox structure
* with cmd information.
* Write the cmd to mbox register
*/
int
lio_mbox_write(struct lio_device *lio_dev,
struct lio_mbox_cmd *mbox_cmd)
{
struct lio_mbox *mbox = lio_dev->mbox[mbox_cmd->q_no];
uint32_t count, i, ret = LIO_MBOX_STATUS_SUCCESS;
if ((mbox_cmd->msg.s.type == LIO_MBOX_RESPONSE) &&
!(mbox->state & LIO_MBOX_STATE_REQ_RECEIVED))
return LIO_MBOX_STATUS_FAILED;
if ((mbox_cmd->msg.s.type == LIO_MBOX_REQUEST) &&
!(mbox->state & LIO_MBOX_STATE_IDLE))
return LIO_MBOX_STATUS_BUSY;
if (mbox_cmd->msg.s.type == LIO_MBOX_REQUEST) {
rte_memcpy(&mbox->mbox_resp, mbox_cmd,
sizeof(struct lio_mbox_cmd));
mbox->state = LIO_MBOX_STATE_RES_PENDING;
}
count = 0;
while (rte_read64(mbox->mbox_write_reg) != LIO_PFVFSIG) {
rte_delay_ms(1);
if (count++ == 1000) {
ret = LIO_MBOX_STATUS_FAILED;
break;
}
}
if (ret == LIO_MBOX_STATUS_SUCCESS) {
rte_write64(mbox_cmd->msg.mbox_msg64, mbox->mbox_write_reg);
for (i = 0; i < (uint32_t)(mbox_cmd->msg.s.len - 1); i++) {
count = 0;
while (rte_read64(mbox->mbox_write_reg) !=
LIO_PFVFACK) {
rte_delay_ms(1);
if (count++ == 1000) {
ret = LIO_MBOX_STATUS_FAILED;
break;
}
}
rte_write64(mbox_cmd->data[i], mbox->mbox_write_reg);
}
}
if (mbox_cmd->msg.s.type == LIO_MBOX_RESPONSE) {
mbox->state = LIO_MBOX_STATE_IDLE;
rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
} else {
if ((!mbox_cmd->msg.s.resp_needed) ||
(ret == LIO_MBOX_STATUS_FAILED)) {
mbox->state &= ~LIO_MBOX_STATE_RES_PENDING;
if (!(mbox->state & (LIO_MBOX_STATE_REQ_RECEIVING |
LIO_MBOX_STATE_REQ_RECEIVED)))
mbox->state = LIO_MBOX_STATE_IDLE;
}
}
return ret;
}
/**
* lio_mbox_process_cmd:
* @mbox: Pointer mailbox
* @mbox_cmd: Pointer to command received
*
* Process the cmd received in mbox
*/
static int
lio_mbox_process_cmd(struct lio_mbox *mbox,
struct lio_mbox_cmd *mbox_cmd)
{
struct lio_device *lio_dev = mbox->lio_dev;
if (mbox_cmd->msg.s.cmd == LIO_CORES_CRASHED)
lio_dev_err(lio_dev, "Octeon core(s) crashed or got stuck!\n");
return 0;
}
/**
* Process the received mbox message.
*/
int
lio_mbox_process_message(struct lio_mbox *mbox)
{
struct lio_mbox_cmd mbox_cmd;
if (mbox->state & LIO_MBOX_STATE_ERROR) {
if (mbox->state & (LIO_MBOX_STATE_RES_PENDING |
LIO_MBOX_STATE_RES_RECEIVING)) {
rte_memcpy(&mbox_cmd, &mbox->mbox_resp,
sizeof(struct lio_mbox_cmd));
mbox->state = LIO_MBOX_STATE_IDLE;
rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
mbox_cmd.recv_status = 1;
if (mbox_cmd.fn)
mbox_cmd.fn(mbox->lio_dev, &mbox_cmd,
mbox_cmd.fn_arg);
return 0;
}
mbox->state = LIO_MBOX_STATE_IDLE;
rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
return 0;
}
if (mbox->state & LIO_MBOX_STATE_RES_RECEIVED) {
rte_memcpy(&mbox_cmd, &mbox->mbox_resp,
sizeof(struct lio_mbox_cmd));
mbox->state = LIO_MBOX_STATE_IDLE;
rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
mbox_cmd.recv_status = 0;
if (mbox_cmd.fn)
mbox_cmd.fn(mbox->lio_dev, &mbox_cmd, mbox_cmd.fn_arg);
return 0;
}
if (mbox->state & LIO_MBOX_STATE_REQ_RECEIVED) {
rte_memcpy(&mbox_cmd, &mbox->mbox_req,
sizeof(struct lio_mbox_cmd));
if (!mbox_cmd.msg.s.resp_needed) {
mbox->state &= ~LIO_MBOX_STATE_REQ_RECEIVED;
if (!(mbox->state & LIO_MBOX_STATE_RES_PENDING))
mbox->state = LIO_MBOX_STATE_IDLE;
rte_write64(LIO_PFVFSIG, mbox->mbox_read_reg);
}
lio_mbox_process_cmd(mbox, &mbox_cmd);
return 0;
}
RTE_ASSERT(0);
return 0;
}