From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Sasha Levin To: "stable@vger.kernel.org" , "linux-kernel@vger.kernel.org" CC: Tomer Tayar , Ariel Elior , "David S . Miller" , Sasha Levin Subject: [PATCH AUTOSEL 4.18 04/56] qed: Wait for ready indication before rereading the shmem Date: Thu, 20 Sep 2018 02:47:28 +0000 Message-ID: <20180920024716.58490-4-alexander.levin@microsoft.com> References: <20180920024716.58490-1-alexander.levin@microsoft.com> In-Reply-To: <20180920024716.58490-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: From: Tomer Tayar [ Upstream commit f00d25f3154b676fcea4502a25b94bd7f142ca74 ] 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: Tomer Tayar Signed-off-by: Ariel Elior Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/qlogic/qed/qed_mcp.c | 50 +++++++++++++++++++---- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethern= et/qlogic/qed/qed_mcp.c index cdd645024a32..f3937491d545 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c @@ -183,18 +183,57 @@ int qed_mcp_free(struct qed_hwfn *p_hwfn) return 0; } =20 +/* 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 =3D p_hwfn->mcp_info; + u8 cnt =3D QED_MCP_SHMEM_RDY_MAX_RETRIES; + u8 msec =3D QED_MCP_SHMEM_RDY_ITER_MS; u32 drv_mb_offsize, mfw_mb_offsize; u32 mcp_pf_id =3D MCP_PF_ID(p_hwfn); =20 p_info->public_base =3D 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; + } =20 p_info->public_base |=3D GRCBASE_MCP; =20 + /* Get the MFW MB address and number of supported messages */ + mfw_mb_offsize =3D qed_rd(p_hwfn, p_ptt, + SECTION_OFFSIZE_ADDR(p_info->public_base, + PUBLIC_MFW_MB)); + p_info->mfw_mb_addr =3D SECTION_ADDR(mfw_mb_offsize, mcp_pf_id); + p_info->mfw_mb_length =3D (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 =3D + (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 =3D 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_hwf= n, struct qed_ptt *p_ptt) "drv_mb_offsiz =3D 0x%x, drv_mb_addr =3D 0x%x mcp_pf_id =3D 0x%x\n", drv_mb_offsize, p_info->drv_mb_addr, mcp_pf_id); =20 - /* Set the MFW MB address */ - mfw_mb_offsize =3D qed_rd(p_hwfn, p_ptt, - SECTION_OFFSIZE_ADDR(p_info->public_base, - PUBLIC_MFW_MB)); - p_info->mfw_mb_addr =3D SECTION_ADDR(mfw_mb_offsize, mcp_pf_id); - p_info->mfw_mb_length =3D (u16)qed_rd(p_hwfn, p_ptt, p_info->mfw_mb_addr)= ; - /* Get the current driver mailbox sequence before sending * the first command */ --=20 2.17.1