Commit bd8ed441 authored by Pavel Belous's avatar Pavel Belous Committed by David S. Miller

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: default avatarPavel Belous <Pavel.Belous@aquantia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0a402e7b
...@@ -105,8 +105,7 @@ struct aq_hw_ops { ...@@ -105,8 +105,7 @@ struct aq_hw_ops {
int (*hw_set_mac_address)(struct aq_hw_s *self, u8 *mac_addr); int (*hw_set_mac_address)(struct aq_hw_s *self, u8 *mac_addr);
int (*hw_get_link_status)(struct aq_hw_s *self, int (*hw_get_link_status)(struct aq_hw_s *self);
struct aq_hw_link_status_s *link_status);
int (*hw_set_link_speed)(struct aq_hw_s *self, u32 speed); int (*hw_set_link_speed)(struct aq_hw_s *self, u32 speed);
......
...@@ -125,33 +125,30 @@ static void aq_nic_service_timer_cb(unsigned long param) ...@@ -125,33 +125,30 @@ static void aq_nic_service_timer_cb(unsigned long param)
struct net_device *ndev = aq_nic_get_ndev(self); struct net_device *ndev = aq_nic_get_ndev(self);
int err = 0; int err = 0;
unsigned int i = 0U; unsigned int i = 0U;
struct aq_hw_link_status_s link_status;
struct aq_ring_stats_rx_s stats_rx; struct aq_ring_stats_rx_s stats_rx;
struct aq_ring_stats_tx_s stats_tx; struct aq_ring_stats_tx_s stats_tx;
if (aq_utils_obj_test(&self->header.flags, AQ_NIC_FLAGS_IS_NOT_READY)) if (aq_utils_obj_test(&self->header.flags, AQ_NIC_FLAGS_IS_NOT_READY))
goto err_exit; goto err_exit;
err = self->aq_hw_ops.hw_get_link_status(self->aq_hw, &link_status); err = self->aq_hw_ops.hw_get_link_status(self->aq_hw);
if (err < 0) if (err < 0)
goto err_exit; goto err_exit;
self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw, self->link_status = self->aq_hw->aq_link_status;
self->aq_nic_cfg.is_interrupt_moderation);
if (memcmp(&link_status, &self->link_status, sizeof(link_status))) {
if (link_status.mbps) {
aq_utils_obj_set(&self->header.flags,
AQ_NIC_FLAG_STARTED);
aq_utils_obj_clear(&self->header.flags,
AQ_NIC_LINK_DOWN);
netif_carrier_on(self->ndev);
} else {
netif_carrier_off(self->ndev);
aq_utils_obj_set(&self->header.flags, AQ_NIC_LINK_DOWN);
}
self->link_status = link_status; self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,
self->aq_nic_cfg.is_interrupt_moderation);
if (self->link_status.mbps) {
aq_utils_obj_set(&self->header.flags,
AQ_NIC_FLAG_STARTED);
aq_utils_obj_clear(&self->header.flags,
AQ_NIC_LINK_DOWN);
netif_carrier_on(self->ndev);
} else {
netif_carrier_off(self->ndev);
aq_utils_obj_set(&self->header.flags, AQ_NIC_LINK_DOWN);
} }
memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s)); memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s));
......
...@@ -313,11 +313,11 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self, ...@@ -313,11 +313,11 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self,
err_exit:; err_exit:;
} }
int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self, int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
struct aq_hw_link_status_s *link_status)
{ {
u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR); u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT; u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;
struct aq_hw_link_status_s *link_status = &self->aq_link_status;
if (!link_speed_mask) { if (!link_speed_mask) {
link_status->mbps = 0U; link_status->mbps = 0U;
......
...@@ -180,8 +180,7 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self, ...@@ -180,8 +180,7 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self,
int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed, int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed,
enum hal_atl_utils_fw_state_e state); enum hal_atl_utils_fw_state_e state);
int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self, int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self);
struct aq_hw_link_status_s *link_status);
int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self, int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
struct aq_hw_caps_s *aq_hw_caps, struct aq_hw_caps_s *aq_hw_caps,
......
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