[PATCH 4.18 172/228] qed: Wait for ready indication before rereading the shmem

2018-10-02 Thread Greg Kroah-Hartman
4.18-stable review patch.  If anyone has any objections, please let me know.

--

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 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/net/ethernet/qlogic/qed/qed_mcp.c |   50 --
 1 file changed, 41 insertions(+), 9 deletions(-)

--- 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;
 }
 
+/* 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 q
   "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
 */




[PATCH 4.18 172/228] qed: Wait for ready indication before rereading the shmem

2018-10-02 Thread Greg Kroah-Hartman
4.18-stable review patch.  If anyone has any objections, please let me know.

--

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 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/net/ethernet/qlogic/qed/qed_mcp.c |   50 --
 1 file changed, 41 insertions(+), 9 deletions(-)

--- 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;
 }
 
+/* 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 q
   "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
 */