]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.9.131/qed-wait-for-ready-indication-before-rereading-the-shmem.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.9.131 / qed-wait-for-ready-indication-before-rereading-the-shmem.patch
1 From foo@baz Tue Oct 2 05:02:12 PDT 2018
2 From: Tomer Tayar <Tomer.Tayar@cavium.com>
3 Date: Mon, 20 Aug 2018 00:01:42 +0300
4 Subject: qed: Wait for ready indication before rereading the shmem
5
6 From: Tomer Tayar <Tomer.Tayar@cavium.com>
7
8 [ Upstream commit f00d25f3154b676fcea4502a25b94bd7f142ca74 ]
9
10 The MFW might be reset and re-update its shared memory.
11 Upon the detection of such a reset the driver rereads this memory, but it
12 has to wait till the data is valid.
13 This patch adds the missing wait for a data ready indication.
14
15 Signed-off-by: Tomer Tayar <Tomer.Tayar@cavium.com>
16 Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
17 Signed-off-by: David S. Miller <davem@davemloft.net>
18 Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
19 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
20 ---
21 drivers/net/ethernet/qlogic/qed/qed_mcp.c | 50 ++++++++++++++++++++++++------
22 1 file changed, 41 insertions(+), 9 deletions(-)
23
24 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
25 +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
26 @@ -97,18 +97,57 @@ int qed_mcp_free(struct qed_hwfn *p_hwfn
27 return 0;
28 }
29
30 +/* Maximum of 1 sec to wait for the SHMEM ready indication */
31 +#define QED_MCP_SHMEM_RDY_MAX_RETRIES 20
32 +#define QED_MCP_SHMEM_RDY_ITER_MS 50
33 +
34 static int qed_load_mcp_offsets(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
35 {
36 struct qed_mcp_info *p_info = p_hwfn->mcp_info;
37 + u8 cnt = QED_MCP_SHMEM_RDY_MAX_RETRIES;
38 + u8 msec = QED_MCP_SHMEM_RDY_ITER_MS;
39 u32 drv_mb_offsize, mfw_mb_offsize;
40 u32 mcp_pf_id = MCP_PF_ID(p_hwfn);
41
42 p_info->public_base = qed_rd(p_hwfn, p_ptt, MISC_REG_SHARED_MEM_ADDR);
43 - if (!p_info->public_base)
44 - return 0;
45 + if (!p_info->public_base) {
46 + DP_NOTICE(p_hwfn,
47 + "The address of the MCP scratch-pad is not configured\n");
48 + return -EINVAL;
49 + }
50
51 p_info->public_base |= GRCBASE_MCP;
52
53 + /* Get the MFW MB address and number of supported messages */
54 + mfw_mb_offsize = qed_rd(p_hwfn, p_ptt,
55 + SECTION_OFFSIZE_ADDR(p_info->public_base,
56 + PUBLIC_MFW_MB));
57 + p_info->mfw_mb_addr = SECTION_ADDR(mfw_mb_offsize, mcp_pf_id);
58 + p_info->mfw_mb_length = (u16)qed_rd(p_hwfn, p_ptt,
59 + p_info->mfw_mb_addr +
60 + offsetof(struct public_mfw_mb,
61 + sup_msgs));
62 +
63 + /* The driver can notify that there was an MCP reset, and might read the
64 + * SHMEM values before the MFW has completed initializing them.
65 + * To avoid this, the "sup_msgs" field in the MFW mailbox is used as a
66 + * data ready indication.
67 + */
68 + while (!p_info->mfw_mb_length && --cnt) {
69 + msleep(msec);
70 + p_info->mfw_mb_length =
71 + (u16)qed_rd(p_hwfn, p_ptt,
72 + p_info->mfw_mb_addr +
73 + offsetof(struct public_mfw_mb, sup_msgs));
74 + }
75 +
76 + if (!cnt) {
77 + DP_NOTICE(p_hwfn,
78 + "Failed to get the SHMEM ready notification after %d msec\n",
79 + QED_MCP_SHMEM_RDY_MAX_RETRIES * msec);
80 + return -EBUSY;
81 + }
82 +
83 /* Calculate the driver and MFW mailbox address */
84 drv_mb_offsize = qed_rd(p_hwfn, p_ptt,
85 SECTION_OFFSIZE_ADDR(p_info->public_base,
86 @@ -118,13 +157,6 @@ static int qed_load_mcp_offsets(struct q
87 "drv_mb_offsiz = 0x%x, drv_mb_addr = 0x%x mcp_pf_id = 0x%x\n",
88 drv_mb_offsize, p_info->drv_mb_addr, mcp_pf_id);
89
90 - /* Set the MFW MB address */
91 - mfw_mb_offsize = qed_rd(p_hwfn, p_ptt,
92 - SECTION_OFFSIZE_ADDR(p_info->public_base,
93 - PUBLIC_MFW_MB));
94 - p_info->mfw_mb_addr = SECTION_ADDR(mfw_mb_offsize, mcp_pf_id);
95 - p_info->mfw_mb_length = (u16)qed_rd(p_hwfn, p_ptt, p_info->mfw_mb_addr);
96 -
97 /* Get the current driver mailbox sequence before sending
98 * the first command
99 */