diff options
author | Igor Russkikh <igor.russkikh@aquantia.com> | 2018-07-02 17:03:36 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-07-03 23:23:48 +0900 |
commit | 44e00dd8eb94b894b7f60009c251acf24b8bbaf1 (patch) | |
tree | 442b3246e74a8e3829490184f5fdfb4a88bcc671 /drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c | |
parent | net: aquantia: Ethtool based ring size configuration (diff) | |
download | linux-dev-44e00dd8eb94b894b7f60009c251acf24b8bbaf1.tar.xz linux-dev-44e00dd8eb94b894b7f60009c251acf24b8bbaf1.zip |
net: aquantia: Improve adapter init/deinit logic
We now pass link drop status to FW on init/deinit. This is required
to inform FW that driver took/released a control on link.
FW then will manage its own state and device power profile based
on this information. To improve management we remove mpi_set
function which ambiguously took both state and speed parameters.
Deinit callback is now a part of FW ops, as it actually manages the FW.
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to '')
-rw-r--r-- | drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c index 39cd3a27fe77..a3e95f076bf0 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c @@ -28,6 +28,10 @@ #define HW_ATL_FW2X_MPI_STATE_ADDR 0x370 #define HW_ATL_FW2X_MPI_STATE2_ADDR 0x374 +static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed); +static int aq_fw2x_set_state(struct aq_hw_s *self, + enum hal_atl_utils_fw_state_e state); + static int aq_fw2x_init(struct aq_hw_s *self) { int err = 0; @@ -39,6 +43,16 @@ static int aq_fw2x_init(struct aq_hw_s *self) return err; } +static int aq_fw2x_deinit(struct aq_hw_s *self) +{ + int err = aq_fw2x_set_link_speed(self, 0); + + if (!err) + err = aq_fw2x_set_state(self, MPI_DEINIT); + + return err; +} + static enum hw_atl_fw2x_rate link_speed_mask_2fw2x_ratemask(u32 speed) { enum hw_atl_fw2x_rate rate = 0; @@ -76,7 +90,21 @@ static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed) static int aq_fw2x_set_state(struct aq_hw_s *self, enum hal_atl_utils_fw_state_e state) { - /* No explicit state in 2x fw */ + u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); + + switch (state) { + case MPI_INIT: + mpi_state &= ~BIT(CAPS_HI_LINK_DROP); + break; + case MPI_DEINIT: + mpi_state |= BIT(CAPS_HI_LINK_DROP); + break; + case MPI_RESET: + case MPI_POWER: + /* No actions */ + break; + } + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state); return 0; } @@ -175,6 +203,7 @@ static int aq_fw2x_update_stats(struct aq_hw_s *self) const struct aq_fw_ops aq_fw_2x_ops = { .init = aq_fw2x_init, + .deinit = aq_fw2x_deinit, .reset = NULL, .get_mac_permanent = aq_fw2x_get_mac_permanent, .set_link_speed = aq_fw2x_set_link_speed, |