diff mbox

[net,4/7] net:ethernet:aquantia: Fix for MCP state change.

Message ID daa58e36851b90b099ade078270bff7cf2872787.1503496727.git.pavel.belous@aquantia.com
State Changes Requested, archived
Delegated to: David Miller
Headers show

Commit Message

Pavel Belous Aug. 23, 2017, 2:05 p.m. UTC
From: Pavel Belous <pavel.belous@aquantia.com>

The firmware state is controlled by writing value in to 0x368 register.
This value contain MCP state and desired link mode.
Because this value was incorrectly formed the firmware does not
resetting properly (ethtool -S shows the HW counters which
never resetting, even after reboot).

Fixes: 3d2ff7eebe26 "net: ethernet: aquantia: Atlantic hardware abstraction layer")
Signed-off-by: Pavel Belous <Pavel.Belous@aquantia.com>
---
 .../net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c    |  7 ++++---
 .../net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h    | 13 +++++++++++++
 2 files changed, 17 insertions(+), 3 deletions(-)

Comments

David Miller Aug. 24, 2017, 5:17 a.m. UTC | #1
From: Pavel Belous <Pavel.Belous@aquantia.com>
Date: Wed, 23 Aug 2017 17:05:05 +0300

> diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
> index a66aee5..fc69408a 100644
> --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
> +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
> @@ -160,6 +160,19 @@ enum hal_atl_utils_fw_state_e {
>  	MPI_POWER = 4,
>  };
>  
> +union hal_atl_utils_hw_mpi_state_reg {
> +	u32 val;
> +	struct {
> +		u8 e_state;
> +		u8 reserved1;
> +		u8 u_speed;
> +		u8 reserved2:1;
> +		u8 disable_dirty_wake:1;
> +		u8 reserved3:2;
> +		u8 u_downshift:4;
> +	};
> +};
> +

You need to consider endianness when declaring bitfields in C.

Seriously, I'd rather you simply fixed the shifts and masks into the
u32 value than going down this route.
diff mbox

Patch

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 8d6d8f5..fcfbe42 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
@@ -280,10 +280,11 @@  err_exit:;
 int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed,
 			       enum hal_atl_utils_fw_state_e state)
 {
-	u32 ucp_0x368 = 0;
+	union hal_atl_utils_hw_mpi_state_reg ucp_0x368 = { 0 };
 
-	ucp_0x368 = (speed << HW_ATL_MPI_SPEED_SHIFT) | state;
-	aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, ucp_0x368);
+	ucp_0x368.u_speed = speed;
+	ucp_0x368.e_state = state;
+	aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, ucp_0x368.val);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
index a66aee5..fc69408a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -160,6 +160,19 @@  enum hal_atl_utils_fw_state_e {
 	MPI_POWER = 4,
 };
 
+union hal_atl_utils_hw_mpi_state_reg {
+	u32 val;
+	struct {
+		u8 e_state;
+		u8 reserved1;
+		u8 u_speed;
+		u8 reserved2:1;
+		u8 disable_dirty_wake:1;
+		u8 reserved3:2;
+		u8 u_downshift:4;
+	};
+};
+
 #define HAL_ATLANTIC_RATE_10G        BIT(0)
 #define HAL_ATLANTIC_RATE_5G         BIT(1)
 #define HAL_ATLANTIC_RATE_5GSR       BIT(2)