#include "lio_bsd.h"
#include "lio_common.h"
#include "lio_droq.h"
#include "lio_iq.h"
#include "lio_response_manager.h"
#include "lio_device.h"
#include "lio_ctrl.h"
#include "lio_main.h"
int
lio_send_data_pkt(struct octeon_device *oct, struct lio_data_pkt *ndata)
{
int ring_doorbell = 1;
return (lio_send_command(oct, ndata->q_no, ring_doorbell, &ndata->cmd,
ndata->buf, ndata->datasize, ndata->reqtype));
}
static void
lio_ctrl_callback(struct octeon_device *oct, uint32_t status, void *sc_ptr)
{
struct lio_soft_command *sc = (struct lio_soft_command *)sc_ptr;
struct lio_ctrl_pkt *nctrl;
nctrl = (struct lio_ctrl_pkt *)sc->ctxptr;
if (!status && nctrl->cb_fn)
nctrl->cb_fn(nctrl);
lio_free_soft_command(oct, sc);
}
static inline struct lio_soft_command *
lio_alloc_ctrl_pkt_sc(struct octeon_device *oct, struct lio_ctrl_pkt *nctrl)
{
struct lio_soft_command *sc = NULL;
uint32_t datasize = 0, rdatasize, uddsize = 0;
uint8_t *data;
uddsize = (uint32_t)(nctrl->ncmd.s.more * 8);
datasize = OCTEON_CMD_SIZE + uddsize;
rdatasize = (nctrl->wait_time) ? 16 : 0;
sc = lio_alloc_soft_command(oct, datasize, rdatasize,
sizeof(struct lio_ctrl_pkt));
if (sc == NULL)
return (NULL);
memcpy(sc->ctxptr, nctrl, sizeof(struct lio_ctrl_pkt));
data = (uint8_t *)sc->virtdptr;
memcpy(data, &nctrl->ncmd, OCTEON_CMD_SIZE);
lio_swap_8B_data((uint64_t *)data, (OCTEON_CMD_SIZE >> 3));
if (uddsize) {
memcpy(data + OCTEON_CMD_SIZE, nctrl->udd, uddsize);
}
sc->iq_no = (uint32_t)nctrl->iq_no;
lio_prepare_soft_command(oct, sc, LIO_OPCODE_NIC, LIO_OPCODE_NIC_CMD, 0,
0, 0);
sc->callback = lio_ctrl_callback;
sc->callback_arg = sc;
sc->wait_time = nctrl->wait_time;
return (sc);
}
int
lio_send_ctrl_pkt(struct octeon_device *oct, struct lio_ctrl_pkt *nctrl)
{
struct lio_soft_command *sc = NULL;
int retval;
mtx_lock(&oct->cmd_resp_wqlock);
if ((oct->cmd_resp_state == LIO_DRV_OFFLINE) &&
(nctrl->ncmd.s.cmd != LIO_CMD_RX_CTL)) {
mtx_unlock(&oct->cmd_resp_wqlock);
lio_dev_err(oct, "%s cmd:%d not processed since driver offline\n",
__func__, nctrl->ncmd.s.cmd);
return (-1);
}
sc = lio_alloc_ctrl_pkt_sc(oct, nctrl);
if (sc == NULL) {
lio_dev_err(oct, "%s soft command alloc failed\n", __func__);
mtx_unlock(&oct->cmd_resp_wqlock);
return (-1);
}
retval = lio_send_soft_command(oct, sc);
if (retval == LIO_IQ_SEND_FAILED) {
lio_free_soft_command(oct, sc);
lio_dev_err(oct, "%s pf_num:%d soft command:%d send failed status: %x\n",
__func__, oct->pf_num, nctrl->ncmd.s.cmd, retval);
mtx_unlock(&oct->cmd_resp_wqlock);
return (-1);
}
mtx_unlock(&oct->cmd_resp_wqlock);
return (retval);
}