diff options
author | Pavel Belous <pavel.belous@aquantia.com> | 2017-08-28 14:52:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-08-29 18:11:44 -0400 |
commit | bd8ed4415ff8584ccdd1f61c8d7279dc1f9e623e (patch) | |
tree | 2c64fbbb2d56b78d8c91aaaac617ddbad38a043a | |
parent | 0a402e7b9725611069dad4c873d1516f8c805f38 (diff) |
net:ethernet:aquantia: Fix for incorrect speed index.
The driver choose the optimal interrupt throttling settings depends
of current link speed.
Due this bug link_status field from aq_hw is never updated and as result
always used same interrupt throttling values.
Fixes: 3d2ff7eebe26 ("net: ethernet: aquantia: Atlantic hardware abstraction layer")
Signed-off-by: Pavel Belous <Pavel.Belous@aquantia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
4 files changed, 18 insertions, 23 deletions
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h index fce0fd3f23ff..bf9b3f020e10 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h | |||
@@ -105,8 +105,7 @@ struct aq_hw_ops { | |||
105 | 105 | ||
106 | int (*hw_set_mac_address)(struct aq_hw_s *self, u8 *mac_addr); | 106 | int (*hw_set_mac_address)(struct aq_hw_s *self, u8 *mac_addr); |
107 | 107 | ||
108 | int (*hw_get_link_status)(struct aq_hw_s *self, | 108 | int (*hw_get_link_status)(struct aq_hw_s *self); |
109 | struct aq_hw_link_status_s *link_status); | ||
110 | 109 | ||
111 | int (*hw_set_link_speed)(struct aq_hw_s *self, u32 speed); | 110 | int (*hw_set_link_speed)(struct aq_hw_s *self, u32 speed); |
112 | 111 | ||
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index d6d8e7074c83..dce17a5b82b1 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c | |||
@@ -125,33 +125,30 @@ static void aq_nic_service_timer_cb(unsigned long param) | |||
125 | struct net_device *ndev = aq_nic_get_ndev(self); | 125 | struct net_device *ndev = aq_nic_get_ndev(self); |
126 | int err = 0; | 126 | int err = 0; |
127 | unsigned int i = 0U; | 127 | unsigned int i = 0U; |
128 | struct aq_hw_link_status_s link_status; | ||
129 | struct aq_ring_stats_rx_s stats_rx; | 128 | struct aq_ring_stats_rx_s stats_rx; |
130 | struct aq_ring_stats_tx_s stats_tx; | 129 | struct aq_ring_stats_tx_s stats_tx; |
131 | 130 | ||
132 | if (aq_utils_obj_test(&self->header.flags, AQ_NIC_FLAGS_IS_NOT_READY)) | 131 | if (aq_utils_obj_test(&self->header.flags, AQ_NIC_FLAGS_IS_NOT_READY)) |
133 | goto err_exit; | 132 | goto err_exit; |
134 | 133 | ||
135 | err = self->aq_hw_ops.hw_get_link_status(self->aq_hw, &link_status); | 134 | err = self->aq_hw_ops.hw_get_link_status(self->aq_hw); |
136 | if (err < 0) | 135 | if (err < 0) |
137 | goto err_exit; | 136 | goto err_exit; |
138 | 137 | ||
139 | self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw, | 138 | self->link_status = self->aq_hw->aq_link_status; |
140 | self->aq_nic_cfg.is_interrupt_moderation); | ||
141 | |||
142 | if (memcmp(&link_status, &self->link_status, sizeof(link_status))) { | ||
143 | if (link_status.mbps) { | ||
144 | aq_utils_obj_set(&self->header.flags, | ||
145 | AQ_NIC_FLAG_STARTED); | ||
146 | aq_utils_obj_clear(&self->header.flags, | ||
147 | AQ_NIC_LINK_DOWN); | ||
148 | netif_carrier_on(self->ndev); | ||
149 | } else { | ||
150 | netif_carrier_off(self->ndev); | ||
151 | aq_utils_obj_set(&self->header.flags, AQ_NIC_LINK_DOWN); | ||
152 | } | ||
153 | 139 | ||
154 | self->link_status = link_status; | 140 | self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw, |
141 | self->aq_nic_cfg.is_interrupt_moderation); | ||
142 | |||
143 | if (self->link_status.mbps) { | ||
144 | aq_utils_obj_set(&self->header.flags, | ||
145 | AQ_NIC_FLAG_STARTED); | ||
146 | aq_utils_obj_clear(&self->header.flags, | ||
147 | AQ_NIC_LINK_DOWN); | ||
148 | netif_carrier_on(self->ndev); | ||
149 | } else { | ||
150 | netif_carrier_off(self->ndev); | ||
151 | aq_utils_obj_set(&self->header.flags, AQ_NIC_LINK_DOWN); | ||
155 | } | 152 | } |
156 | 153 | ||
157 | memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s)); | 154 | memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s)); |
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 8d6d8f5804da..7a1332e9b9bc 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 | |||
@@ -313,11 +313,11 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self, | |||
313 | err_exit:; | 313 | err_exit:; |
314 | } | 314 | } |
315 | 315 | ||
316 | int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self, | 316 | int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self) |
317 | struct aq_hw_link_status_s *link_status) | ||
318 | { | 317 | { |
319 | u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR); | 318 | u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR); |
320 | u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT; | 319 | u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT; |
320 | struct aq_hw_link_status_s *link_status = &self->aq_link_status; | ||
321 | 321 | ||
322 | if (!link_speed_mask) { | 322 | if (!link_speed_mask) { |
323 | link_status->mbps = 0U; | 323 | link_status->mbps = 0U; |
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 a66aee51ab5b..e0360a6b2202 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 | |||
@@ -180,8 +180,7 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self, | |||
180 | int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed, | 180 | int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed, |
181 | enum hal_atl_utils_fw_state_e state); | 181 | enum hal_atl_utils_fw_state_e state); |
182 | 182 | ||
183 | int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self, | 183 | int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self); |
184 | struct aq_hw_link_status_s *link_status); | ||
185 | 184 | ||
186 | int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self, | 185 | int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self, |
187 | struct aq_hw_caps_s *aq_hw_caps, | 186 | struct aq_hw_caps_s *aq_hw_caps, |