dpdk/drivers/net/liquidio/base/lio_mbox.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2017 Cavium, Inc
   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 * lio_mbox_read:
  14 * @mbox: Pointer mailbox
  15 *
  16 * Reads the 8-bytes of data from the mbox register
  17 * Writes back the acknowledgment indicating completion of read
  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 * lio_mbox_write:
  98 * @lio_dev: Pointer lio device
  99 * @mbox_cmd: Cmd to send to mailbox.
 100 *
 101 * Populates the queue specific mbox structure
 102 * with cmd information.
 103 * Write the cmd to mbox register
 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 * lio_mbox_process_cmd:
 170 * @mbox: Pointer mailbox
 171 * @mbox_cmd: Pointer to command received
 172 *
 173 * Process the cmd received in mbox
 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 * Process the received mbox message.
 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