static inline void mbox_send_request(struct mbox *m, struct octeontx_mbox_hdr *hdr, const void *txmsg, uint16_t txsize) { struct mbox_ram_hdr old_hdr; struct mbox_ram_hdr new_hdr = { {0} }; uint64_t *ram_mbox_hdr = (uint64_t *)m->ram_mbox_base; uint8_t *ram_mbox_msg = m->ram_mbox_base + sizeof(struct mbox_ram_hdr); /* * Initialize the channel with the tag left by last send. * On success full mbox send complete, PF increments the tag by one. * The sender can validate integrity of PF message with this scheme */ old_hdr.u64 = rte_read64(ram_mbox_hdr); m->tag_own = (old_hdr.tag + 2) & (~0x1ul); /* next even number */ /* Copy msg body */ if (txmsg) mbox_msgcpy(ram_mbox_msg, txmsg, txsize); /* Prepare new hdr */ new_hdr.chan_state = MBOX_CHAN_STATE_REQ; new_hdr.coproc = hdr->coproc; new_hdr.msg = hdr->msg; new_hdr.vfid = hdr->vfid; new_hdr.tag = m->tag_own; new_hdr.len = txsize; /* Write the msg header */ rte_write64(new_hdr.u64, ram_mbox_hdr); rte_smp_wmb(); /* Notify PF about the new msg - write to MBOX reg generates PF IRQ */ rte_write64(0, m->reg); }
static void cn23xx_vf_setup_iq_regs(struct lio_device *lio_dev, uint32_t iq_no) { struct lio_instr_queue *iq = lio_dev->instr_queue[iq_no]; uint64_t pkt_in_done = 0; PMD_INIT_FUNC_TRACE(); /* Write the start of the input queue's ring and its size */ lio_write_csr64(lio_dev, CN23XX_SLI_IQ_BASE_ADDR64(iq_no), iq->base_addr_dma); lio_write_csr(lio_dev, CN23XX_SLI_IQ_SIZE(iq_no), iq->max_count); /* Remember the doorbell & instruction count register addr * for this queue */ iq->doorbell_reg = (uint8_t *)lio_dev->hw_addr + CN23XX_SLI_IQ_DOORBELL(iq_no); iq->inst_cnt_reg = (uint8_t *)lio_dev->hw_addr + CN23XX_SLI_IQ_INSTR_COUNT64(iq_no); lio_dev_dbg(lio_dev, "InstQ[%d]:dbell reg @ 0x%p instcnt_reg @ 0x%p\n", iq_no, iq->doorbell_reg, iq->inst_cnt_reg); /* Store the current instruction counter (used in flush_iq * calculation) */ pkt_in_done = rte_read64(iq->inst_cnt_reg); /* Clear the count by writing back what we read, but don't * enable data traffic here */ rte_write64(pkt_in_done, iq->inst_cnt_reg); }
void cn23xx_vf_handle_mbox(struct lio_device *lio_dev) { uint64_t mbox_int_val; /* read and clear by writing 1 */ mbox_int_val = rte_read64(lio_dev->mbox[0]->mbox_int_reg); rte_write64(mbox_int_val, lio_dev->mbox[0]->mbox_int_reg); if (lio_mbox_read(lio_dev->mbox[0])) lio_mbox_process_message(lio_dev->mbox[0]); }
static inline int mbox_wait_response(struct mbox *m, struct octeontx_mbox_hdr *hdr, void *rxmsg, uint16_t rxsize) { int res = 0, wait; uint16_t len; struct mbox_ram_hdr rx_hdr; uint64_t *ram_mbox_hdr = (uint64_t *)m->ram_mbox_base; uint8_t *ram_mbox_msg = m->ram_mbox_base + sizeof(struct mbox_ram_hdr); /* Wait for response */ wait = MBOX_WAIT_TIME_SEC * 1000 * 10; while (wait > 0) { rte_delay_us(100); rx_hdr.u64 = rte_read64(ram_mbox_hdr); if (rx_hdr.chan_state == MBOX_CHAN_STATE_RES) break; --wait; } hdr->res_code = rx_hdr.res_code; m->tag_own++; /* Timeout */ if (wait <= 0) { res = -ETIMEDOUT; goto error; } /* Tag mismatch */ if (m->tag_own != rx_hdr.tag) { res = -EINVAL; goto error; } /* PF nacked the msg */ if (rx_hdr.res_code != MBOX_RET_SUCCESS) { res = -EBADMSG; goto error; } len = RTE_MIN(rx_hdr.len, rxsize); if (rxmsg) mbox_msgcpy(rxmsg, ram_mbox_msg, len); return len; error: mbox_log_err("Failed to send mbox(%d/%d) coproc=%d msg=%d ret=(%d,%d)", m->tag_own, rx_hdr.tag, hdr->coproc, hdr->msg, res, hdr->res_code); return res; }
/** * 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; }