mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 17:41:44 +00:00
net: atlantic: check rpc result and wait for rpc address
Artificial HW reliability tests revealed a possible hangup in the driver. Normally, when device disappears from bus, all register reads returns 0xFFFFFFFF. At remote procedure invocation towards FW there is a logic where result is compared with -1 in a loop. That caused an infinite loop if hardware due to some issues disappears from bus. Add extra result checks to prevent this. Signed-off-by: Dmitry Bogdanov <dbogdanov@marvell.com> Signed-off-by: Igor Russkikh <irusskikh@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
15beab0a9d
commit
e7b5f97e65
@ -22,6 +22,7 @@
|
||||
#define HW_ATL_MIF_ADDR 0x0208U
|
||||
#define HW_ATL_MIF_VAL 0x020CU
|
||||
|
||||
#define HW_ATL_MPI_RPC_ADDR 0x0334U
|
||||
#define HW_ATL_RPC_CONTROL_ADR 0x0338U
|
||||
#define HW_ATL_RPC_STATE_ADR 0x033CU
|
||||
|
||||
@ -53,15 +54,14 @@ enum mcp_area {
|
||||
};
|
||||
|
||||
static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
|
||||
|
||||
static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
|
||||
enum hal_atl_utils_fw_state_e state);
|
||||
|
||||
static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self);
|
||||
static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self);
|
||||
static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self);
|
||||
static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self);
|
||||
static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self);
|
||||
static u32 aq_fw1x_rpc_get(struct aq_hw_s *self);
|
||||
|
||||
int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
|
||||
{
|
||||
@ -476,6 +476,10 @@ static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
|
||||
self, self->mbox_addr,
|
||||
self->mbox_addr != 0U,
|
||||
1000U, 10000U);
|
||||
err = readx_poll_timeout_atomic(aq_fw1x_rpc_get, self,
|
||||
self->rpc_addr,
|
||||
self->rpc_addr != 0U,
|
||||
1000U, 100000U);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -531,6 +535,12 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
|
||||
self, fw.val,
|
||||
sw.tid == fw.tid,
|
||||
1000U, 100000U);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
err = aq_hw_err_from_flags(self);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
if (fw.len == 0xFFFFU) {
|
||||
err = hw_atl_utils_fw_rpc_call(self, sw.len);
|
||||
@ -1025,6 +1035,11 @@ static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self)
|
||||
return aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR);
|
||||
}
|
||||
|
||||
static u32 aq_fw1x_rpc_get(struct aq_hw_s *self)
|
||||
{
|
||||
return aq_hw_read_reg(self, HW_ATL_MPI_RPC_ADDR);
|
||||
}
|
||||
|
||||
const struct aq_fw_ops aq_fw_1x_ops = {
|
||||
.init = hw_atl_utils_mpi_create,
|
||||
.deinit = hw_atl_fw1x_deinit,
|
||||
|
Loading…
Reference in New Issue
Block a user