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

Commit f00d25f3 authored by Tomer Tayar's avatar Tomer Tayar Committed by David S. Miller
Browse files

qed: Wait for ready indication before rereading the shmem



The MFW might be reset and re-update its shared memory.
Upon the detection of such a reset the driver rereads this memory, but it
has to wait till the data is valid.
This patch adds the missing wait for a data ready indication.

Signed-off-by: default avatarTomer Tayar <Tomer.Tayar@cavium.com>
Signed-off-by: default avatarAriel Elior <Ariel.Elior@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9c86336c
Loading
Loading
Loading
Loading
+41 −9
Original line number Diff line number Diff line
@@ -183,18 +183,57 @@ int qed_mcp_free(struct qed_hwfn *p_hwfn)
	return 0;
}

/* Maximum of 1 sec to wait for the SHMEM ready indication */
#define QED_MCP_SHMEM_RDY_MAX_RETRIES	20
#define QED_MCP_SHMEM_RDY_ITER_MS	50

static int qed_load_mcp_offsets(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{
	struct qed_mcp_info *p_info = p_hwfn->mcp_info;
	u8 cnt = QED_MCP_SHMEM_RDY_MAX_RETRIES;
	u8 msec = QED_MCP_SHMEM_RDY_ITER_MS;
	u32 drv_mb_offsize, mfw_mb_offsize;
	u32 mcp_pf_id = MCP_PF_ID(p_hwfn);

	p_info->public_base = qed_rd(p_hwfn, p_ptt, MISC_REG_SHARED_MEM_ADDR);
	if (!p_info->public_base)
		return 0;
	if (!p_info->public_base) {
		DP_NOTICE(p_hwfn,
			  "The address of the MCP scratch-pad is not configured\n");
		return -EINVAL;
	}

	p_info->public_base |= GRCBASE_MCP;

	/* Get the MFW MB address and number of supported messages */
	mfw_mb_offsize = qed_rd(p_hwfn, p_ptt,
				SECTION_OFFSIZE_ADDR(p_info->public_base,
						     PUBLIC_MFW_MB));
	p_info->mfw_mb_addr = SECTION_ADDR(mfw_mb_offsize, mcp_pf_id);
	p_info->mfw_mb_length = (u16)qed_rd(p_hwfn, p_ptt,
					    p_info->mfw_mb_addr +
					    offsetof(struct public_mfw_mb,
						     sup_msgs));

	/* The driver can notify that there was an MCP reset, and might read the
	 * SHMEM values before the MFW has completed initializing them.
	 * To avoid this, the "sup_msgs" field in the MFW mailbox is used as a
	 * data ready indication.
	 */
	while (!p_info->mfw_mb_length && --cnt) {
		msleep(msec);
		p_info->mfw_mb_length =
			(u16)qed_rd(p_hwfn, p_ptt,
				    p_info->mfw_mb_addr +
				    offsetof(struct public_mfw_mb, sup_msgs));
	}

	if (!cnt) {
		DP_NOTICE(p_hwfn,
			  "Failed to get the SHMEM ready notification after %d msec\n",
			  QED_MCP_SHMEM_RDY_MAX_RETRIES * msec);
		return -EBUSY;
	}

	/* Calculate the driver and MFW mailbox address */
	drv_mb_offsize = qed_rd(p_hwfn, p_ptt,
				SECTION_OFFSIZE_ADDR(p_info->public_base,
@@ -204,13 +243,6 @@ static int qed_load_mcp_offsets(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
		   "drv_mb_offsiz = 0x%x, drv_mb_addr = 0x%x mcp_pf_id = 0x%x\n",
		   drv_mb_offsize, p_info->drv_mb_addr, mcp_pf_id);

	/* Set the MFW MB address */
	mfw_mb_offsize = qed_rd(p_hwfn, p_ptt,
				SECTION_OFFSIZE_ADDR(p_info->public_base,
						     PUBLIC_MFW_MB));
	p_info->mfw_mb_addr = SECTION_ADDR(mfw_mb_offsize, mcp_pf_id);
	p_info->mfw_mb_length =	(u16)qed_rd(p_hwfn, p_ptt, p_info->mfw_mb_addr);

	/* Get the current driver mailbox sequence before sending
	 * the first command
	 */