diff options
author | Nikita Danilov <ndanilov@aquantia.com> | 2019-04-29 10:04:57 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-05-01 09:30:15 -0400 |
commit | f5dce08ab179459f3f622a63dfa446a930b84192 (patch) | |
tree | 96032af50882266d030e56d1418e9a20e8bf9832 /drivers/net/ethernet/aquantia/atlantic/aq_nic.c | |
parent | net: aquantia: user correct MSI irq type (diff) | |
download | linux-dev-f5dce08ab179459f3f622a63dfa446a930b84192.tar.xz linux-dev-f5dce08ab179459f3f622a63dfa446a930b84192.zip |
net: aquantia: introduce fwreq mutex
Some of FW operations could be invoked simultaneously,
from f.e. ethtool context and from service service activity work.
Here we introduce a fw mutex to secure and serialize access
to FW logic.
Signed-off-by: Nikita Danilov <ndanilov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/aquantia/atlantic/aq_nic.c')
-rw-r--r-- | drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index 6de0d1c0ed79..b038e2e9af3a 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -234,8 +234,10 @@ int aq_nic_ndev_register(struct aq_nic_s *self) if (err) goto err_exit; + mutex_lock(&self->fwreq_mutex); err = self->aq_fw_ops->get_mac_permanent(self->aq_hw, self->ndev->dev_addr); + mutex_unlock(&self->fwreq_mutex); if (err) goto err_exit; @@ -304,7 +306,9 @@ int aq_nic_init(struct aq_nic_s *self) unsigned int i = 0U; self->power_state = AQ_HW_POWER_STATE_D0; + mutex_lock(&self->fwreq_mutex); err = self->aq_hw_ops->hw_reset(self->aq_hw); + mutex_unlock(&self->fwreq_mutex); if (err < 0) goto err_exit; @@ -871,7 +875,9 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self, self->aq_nic_cfg.is_autoneg = false; } + mutex_lock(&self->fwreq_mutex); err = self->aq_fw_ops->set_link_speed(self->aq_hw, rate); + mutex_unlock(&self->fwreq_mutex); if (err < 0) goto err_exit; @@ -931,14 +937,22 @@ void aq_nic_deinit(struct aq_nic_s *self) self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) aq_vec_deinit(aq_vec); - self->aq_fw_ops->deinit(self->aq_hw); + if (likely(self->aq_fw_ops->deinit)) { + mutex_lock(&self->fwreq_mutex); + self->aq_fw_ops->deinit(self->aq_hw); + mutex_unlock(&self->fwreq_mutex); + } if (self->power_state != AQ_HW_POWER_STATE_D0 || - self->aq_hw->aq_nic_cfg->wol) { - self->aq_fw_ops->set_power(self->aq_hw, - self->power_state, - self->ndev->dev_addr); - } + self->aq_hw->aq_nic_cfg->wol) + if (likely(self->aq_fw_ops->set_power)) { + mutex_lock(&self->fwreq_mutex); + self->aq_fw_ops->set_power(self->aq_hw, + self->power_state, + self->ndev->dev_addr); + mutex_unlock(&self->fwreq_mutex); + } + err_exit:; } |