You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
3.9 KiB
116 lines
3.9 KiB
From 593e37a318cc7cb70966663a2840b64429d6da63 Mon Sep 17 00:00:00 2001
|
|
From: Igor Russkikh <irusskik@redhat.com>
|
|
Date: Fri, 6 Nov 2020 18:37:15 -0500
|
|
Subject: [PATCH 058/139] [netdrv] net: atlantic: check rpc result and wait for
|
|
rpc address
|
|
|
|
Message-id: <1604687916-15087-59-git-send-email-irusskik@redhat.com>
|
|
Patchwork-id: 338481
|
|
Patchwork-instance: patchwork
|
|
O-Subject: [RHEL8.4 BZ 1857861 058/139] net: atlantic: check rpc result and wait for rpc address
|
|
Bugzilla: 1857861
|
|
RH-Acked-by: David Arcari <darcari@redhat.com>
|
|
RH-Acked-by: John Linville <linville@redhat.com>
|
|
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
|
|
|
|
Bugzilla: http://bugzilla.redhat.com/1857861
|
|
|
|
commit e7b5f97e6574dc4918e375d5f8d24ec31653cd6d
|
|
Author: Igor Russkikh <irusskikh@marvell.com>
|
|
Date: Fri Feb 14 18:44:52 2020 +0300
|
|
|
|
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>
|
|
|
|
Signed-off-by: Igor Russkikh <irusskik@redhat.com>
|
|
|
|
Cc: David Arcari <darcari@redhat.com>
|
|
Cc: Igor Russkikh <irusskik@redhat.com>
|
|
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
|
---
|
|
.../ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c | 19 +++++++++++++++++--
|
|
1 file changed, 17 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
|
|
index f547baa6c954..354705f9bc49 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
|
|
@@ -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,
|
|
--
|
|
2.13.6
|
|
|