コード例 #1
0
ファイル: octeontx_mbox.c プロジェクト: DrenfongWong/dpdk
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);
}
コード例 #2
0
ファイル: lio_23xx_vf.c プロジェクト: Leon555/dpdk
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);
}
コード例 #3
0
ファイル: lio_23xx_vf.c プロジェクト: Leon555/dpdk
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]);
}
コード例 #4
0
ファイル: octeontx_mbox.c プロジェクト: DrenfongWong/dpdk
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;
}
コード例 #5
0
ファイル: lio_mbox.c プロジェクト: DrenfongWong/dpdk
/**
 * 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;
}
コード例 #6
0
ファイル: lio_mbox.c プロジェクト: DrenfongWong/dpdk
/**
 * 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;
}