Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d098192 authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman
Browse files

mei: revamp writing slot counting



Since txe use doorbell and not circular buffer
we have to cheat in write slot counting, txe always consume all the
slots upon write. In order for it to work we need to track
slots using mei_hbuf_empty_slots() instead of tracking it in mei layer

Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6aae48ff
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -436,23 +436,23 @@ unsigned int mei_amthif_poll(struct mei_device *dev,


/**
 * mei_amthif_irq_write_completed - processes completed iamthif operation.
 * mei_amthif_irq_write - write iamthif command in irq thread context.
 *
 * @dev: the device structure.
 * @slots: free slots.
 * @cb_pos: callback block.
 * @cl: private data of the file object.
 * @cmpl_list: complete list.
 *
 * returns 0, OK; otherwise, error.
 */
int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
				  s32 *slots, struct mei_cl_cb *cmpl_list)
int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
			 struct mei_cl_cb *cmpl_list)
{
	struct mei_device *dev = cl->dev;
	struct mei_msg_hdr mei_hdr;
	size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
	u32 msg_slots = mei_data2slots(len);
	int slots;
	int rets;

	rets = mei_cl_flow_ctrl_creds(cl);
@@ -469,13 +469,15 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
	mei_hdr.reserved = 0;
	mei_hdr.internal = 0;

	if (*slots >= msg_slots) {
	slots = mei_hbuf_empty_slots(dev);

	if (slots >= msg_slots) {
		mei_hdr.length = len;
		mei_hdr.msg_complete = 1;
	/* Split the message only if we can write the whole host buffer */
	} else if (*slots == dev->hbuf_depth) {
		msg_slots = *slots;
		len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
	} else if (slots == dev->hbuf_depth) {
		msg_slots = slots;
		len = (slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
		mei_hdr.length = len;
		mei_hdr.msg_complete = 0;
	} else {
@@ -485,7 +487,6 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,

	dev_dbg(&dev->pdev->dev, MEI_HDR_FMT,  MEI_HDR_PRM(&mei_hdr));

	*slots -=  msg_slots;
	rets = mei_write_message(dev, &mei_hdr,
			dev->iamthif_msg_buf + dev->iamthif_msg_buf_index);
	if (rets) {
+9 −10
Original line number Diff line number Diff line
@@ -698,27 +698,26 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
}

/**
 * mei_cl_irq_write_complete - write a message to device
 * mei_cl_irq_write - write a message to device
 *	from the interrupt thread context
 *
 * @cl: client
 * @cb: callback block.
 * @slots: free slots.
 * @cmpl_list: complete list.
 *
 * returns 0, OK; otherwise error.
 */
int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
				     s32 *slots, struct mei_cl_cb *cmpl_list)
int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
		     struct mei_cl_cb *cmpl_list)
{
	struct mei_device *dev;
	struct mei_msg_data *buf;
	struct mei_msg_hdr mei_hdr;
	size_t len;
	u32 msg_slots;
	int slots;
	int rets;


	if (WARN_ON(!cl || !cl->dev))
		return -ENODEV;

@@ -735,6 +734,7 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
		return 0;
	}

	slots = mei_hbuf_empty_slots(dev);
	len = buf->size - cb->buf_idx;
	msg_slots = mei_data2slots(len);

@@ -743,13 +743,13 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
	mei_hdr.reserved = 0;
	mei_hdr.internal = cb->internal;

	if (*slots >= msg_slots) {
	if (slots >= msg_slots) {
		mei_hdr.length = len;
		mei_hdr.msg_complete = 1;
	/* Split the message only if we can write the whole host buffer */
	} else if (*slots == dev->hbuf_depth) {
		msg_slots = *slots;
		len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
	} else if (slots == dev->hbuf_depth) {
		msg_slots = slots;
		len = (slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
		mei_hdr.length = len;
		mei_hdr.msg_complete = 0;
	} else {
@@ -760,7 +760,6 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
	cl_dbg(dev, cl, "buf: size = %d idx = %lu\n",
			cb->request_buffer.size, cb->buf_idx);

	*slots -=  msg_slots;
	rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx);
	if (rets) {
		cl->status = rets;
+2 −2
Original line number Diff line number Diff line
@@ -102,8 +102,8 @@ int mei_cl_disconnect(struct mei_cl *cl);
int mei_cl_connect(struct mei_cl *cl, struct file *file);
int mei_cl_read_start(struct mei_cl *cl, size_t length);
int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking);
int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
				s32 *slots, struct mei_cl_cb *cmpl_list);
int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
		     struct mei_cl_cb *cmpl_list);

void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb);

+1 −1
Original line number Diff line number Diff line
@@ -354,7 +354,7 @@ static int mei_me_write_message(struct mei_device *dev,

	dw_cnt = mei_data2slots(length);
	if (empty_slots < 0 || dw_cnt > empty_slots)
		return -EIO;
		return -EMSGSIZE;

	mei_me_reg_write(hw, H_CB_WW, *((u32 *) header));

+13 −8
Original line number Diff line number Diff line
@@ -566,7 +566,9 @@ static int mei_txe_write(struct mei_device *dev,
	struct mei_txe_hw *hw = to_txe_hw(dev);
	unsigned long rem;
	unsigned long length;
	int slots = dev->hbuf_depth;
	u32 *reg_buf = (u32 *)buf;
	u32 dw_cnt;
	int i;

	if (WARN_ON(!header || !buf))
@@ -576,11 +578,9 @@ static int mei_txe_write(struct mei_device *dev,

	dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header));

	if ((length + sizeof(struct mei_msg_hdr)) > PAYLOAD_SIZE) {
		dev_err(&dev->pdev->dev, "write length exceeded = %ld > %d\n",
			length + sizeof(struct mei_msg_hdr), PAYLOAD_SIZE);
		return -ERANGE;
	}
	dw_cnt = mei_data2slots(length);
	if (dw_cnt > slots)
		return -EMSGSIZE;

	if (WARN(!hw->aliveness, "txe write: aliveness not asserted\n"))
		return -EAGAIN;
@@ -605,6 +605,9 @@ static int mei_txe_write(struct mei_device *dev,
		mei_txe_input_payload_write(dev, i + 1, reg);
	}

	/* after each write the whole buffer is consumed */
	hw->slots = 0;

	/* Set Input-Doorbell */
	mei_txe_input_doorbell_set(hw);

@@ -632,7 +635,8 @@ static size_t mei_txe_hbuf_max_len(const struct mei_device *dev)
 */
static int mei_txe_hbuf_empty_slots(struct mei_device *dev)
{
	return dev->hbuf_depth;
	struct mei_txe_hw *hw = to_txe_hw(dev);
	return hw->slots;
}

/**
@@ -978,11 +982,12 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id)
		}
	}
	/* Input Ready: Detection if host can write to SeC */
	if (test_and_clear_bit(TXE_INTR_IN_READY_BIT, &hw->intr_cause))
	if (test_and_clear_bit(TXE_INTR_IN_READY_BIT, &hw->intr_cause)) {
		dev->hbuf_is_ready = true;
		hw->slots = dev->hbuf_depth;
	}

	if (hw->aliveness && dev->hbuf_is_ready) {

		/* get the real register value */
		dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
		rets = mei_irq_write_handler(dev, &complete_list);
Loading