Commit 98239c90 authored by David S. Miller's avatar David S. Miller

Merge branch 'Aquantia-atlantic-critical-fixes-04-2018'

Igor Russkikh says:

====================
Aquantia atlantic critical fixes 04/2018

Two regressions on latest 4.16 driver reported by users

Some of old FW (1.5.44) had a link management logic which prevents
driver to make clean reset. Driver of 4.16 has a full hardware reset
implemented and that broke the link and traffic on such a cards.

Second is oops on shutdown callback in case interface is already
closed or was never opened.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 53765341 9a11aff2
...@@ -951,9 +951,11 @@ void aq_nic_shutdown(struct aq_nic_s *self) ...@@ -951,9 +951,11 @@ void aq_nic_shutdown(struct aq_nic_s *self)
netif_device_detach(self->ndev); netif_device_detach(self->ndev);
err = aq_nic_stop(self); if (netif_running(self->ndev)) {
if (err < 0) err = aq_nic_stop(self);
goto err_exit; if (err < 0)
goto err_exit;
}
aq_nic_deinit(self); aq_nic_deinit(self);
err_exit: err_exit:
......
...@@ -48,6 +48,8 @@ ...@@ -48,6 +48,8 @@
#define FORCE_FLASHLESS 0 #define FORCE_FLASHLESS 0
static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual); 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);
int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops) int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
{ {
...@@ -247,6 +249,20 @@ int hw_atl_utils_soft_reset(struct aq_hw_s *self) ...@@ -247,6 +249,20 @@ int hw_atl_utils_soft_reset(struct aq_hw_s *self)
self->rbl_enabled = (boot_exit_code != 0); self->rbl_enabled = (boot_exit_code != 0);
/* FW 1.x may bootup in an invalid POWER state (WOL feature).
* We should work around this by forcing its state back to DEINIT
*/
if (!hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
aq_hw_read_reg(self,
HW_ATL_MPI_FW_VERSION))) {
int err = 0;
hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR) &
HW_ATL_MPI_STATE_MSK) == MPI_DEINIT,
10, 1000U);
}
if (self->rbl_enabled) if (self->rbl_enabled)
return hw_atl_utils_soft_reset_rbl(self); return hw_atl_utils_soft_reset_rbl(self);
else else
......
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