Commit 76271809 authored by Tomer Tayar's avatar Tomer Tayar Committed by David S. Miller

qed: Wait for MCP halt and resume commands to take place

Successive iterations of halting and resuming the management chip (MCP)
might fail, since currently the driver doesn't wait for these operations to
actually take place.
This patch prevents the driver from moving forward before the operations
are reflected in the state register.
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 f00d25f3
...@@ -2109,31 +2109,61 @@ qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn, ...@@ -2109,31 +2109,61 @@ qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn,
return rc; return rc;
} }
/* A maximal 100 msec waiting time for the MCP to halt */
#define QED_MCP_HALT_SLEEP_MS 10
#define QED_MCP_HALT_MAX_RETRIES 10
int qed_mcp_halt(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) int qed_mcp_halt(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{ {
u32 resp = 0, param = 0; u32 resp = 0, param = 0, cpu_state, cnt = 0;
int rc; int rc;
rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_MCP_HALT, 0, &resp, rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_MCP_HALT, 0, &resp,
&param); &param);
if (rc) if (rc) {
DP_ERR(p_hwfn, "MCP response failure, aborting\n"); DP_ERR(p_hwfn, "MCP response failure, aborting\n");
return rc; return rc;
}
do {
msleep(QED_MCP_HALT_SLEEP_MS);
cpu_state = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_STATE);
if (cpu_state & MCP_REG_CPU_STATE_SOFT_HALTED)
break;
} while (++cnt < QED_MCP_HALT_MAX_RETRIES);
if (cnt == QED_MCP_HALT_MAX_RETRIES) {
DP_NOTICE(p_hwfn,
"Failed to halt the MCP [CPU_MODE = 0x%08x, CPU_STATE = 0x%08x]\n",
qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE), cpu_state);
return -EBUSY;
}
return 0;
} }
#define QED_MCP_RESUME_SLEEP_MS 10
int qed_mcp_resume(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) int qed_mcp_resume(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{ {
u32 value, cpu_mode; u32 cpu_mode, cpu_state;
qed_wr(p_hwfn, p_ptt, MCP_REG_CPU_STATE, 0xffffffff); qed_wr(p_hwfn, p_ptt, MCP_REG_CPU_STATE, 0xffffffff);
value = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE);
value &= ~MCP_REG_CPU_MODE_SOFT_HALT;
qed_wr(p_hwfn, p_ptt, MCP_REG_CPU_MODE, value);
cpu_mode = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE); cpu_mode = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE);
cpu_mode &= ~MCP_REG_CPU_MODE_SOFT_HALT;
qed_wr(p_hwfn, p_ptt, MCP_REG_CPU_MODE, cpu_mode);
msleep(QED_MCP_RESUME_SLEEP_MS);
cpu_state = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_STATE);
return (cpu_mode & MCP_REG_CPU_MODE_SOFT_HALT) ? -EAGAIN : 0; if (cpu_state & MCP_REG_CPU_STATE_SOFT_HALTED) {
DP_NOTICE(p_hwfn,
"Failed to resume the MCP [CPU_MODE = 0x%08x, CPU_STATE = 0x%08x]\n",
cpu_mode, cpu_state);
return -EBUSY;
}
return 0;
} }
int qed_mcp_ov_update_current_config(struct qed_hwfn *p_hwfn, int qed_mcp_ov_update_current_config(struct qed_hwfn *p_hwfn,
......
...@@ -562,6 +562,7 @@ ...@@ -562,6 +562,7 @@
0 0
#define MCP_REG_CPU_STATE \ #define MCP_REG_CPU_STATE \
0xe05004UL 0xe05004UL
#define MCP_REG_CPU_STATE_SOFT_HALTED (0x1UL << 10)
#define MCP_REG_CPU_EVENT_MASK \ #define MCP_REG_CPU_EVENT_MASK \
0xe05008UL 0xe05008UL
#define PGLUE_B_REG_PF_BAR0_SIZE \ #define PGLUE_B_REG_PF_BAR0_SIZE \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment