All changes related to bp->link_info require the protection of the
link_lock mutex.  It's not sufficient to rely just on RTNL.

Fixes: 163e9ef63641 ("bnxt_en: Fix race when modifying pause settings.")
Reviewed-by: Edwin Peer <edwin.p...@broadcom.com>
Signed-off-by: Michael Chan <michael.c...@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 31 +++++++++++++++--------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c 
b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index d092833..6c75101 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -1788,9 +1788,12 @@ static int bnxt_set_pauseparam(struct net_device *dev,
        if (!BNXT_PHY_CFG_ABLE(bp))
                return -EOPNOTSUPP;
 
+       mutex_lock(&bp->link_lock);
        if (epause->autoneg) {
-               if (!(link_info->autoneg & BNXT_AUTONEG_SPEED))
-                       return -EINVAL;
+               if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) {
+                       rc = -EINVAL;
+                       goto pause_exit;
+               }
 
                link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL;
                if (bp->hwrm_spec_code >= 0x10201)
@@ -1811,11 +1814,11 @@ static int bnxt_set_pauseparam(struct net_device *dev,
        if (epause->tx_pause)
                link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_TX;
 
-       if (netif_running(dev)) {
-               mutex_lock(&bp->link_lock);
+       if (netif_running(dev))
                rc = bnxt_hwrm_set_pause(bp);
-               mutex_unlock(&bp->link_lock);
-       }
+
+pause_exit:
+       mutex_unlock(&bp->link_lock);
        return rc;
 }
 
@@ -2552,8 +2555,7 @@ static int bnxt_set_eee(struct net_device *dev, struct 
ethtool_eee *edata)
        struct bnxt *bp = netdev_priv(dev);
        struct ethtool_eee *eee = &bp->eee;
        struct bnxt_link_info *link_info = &bp->link_info;
-       u32 advertising =
-                _bnxt_fw_to_ethtool_adv_spds(link_info->advertising, 0);
+       u32 advertising;
        int rc = 0;
 
        if (!BNXT_PHY_CFG_ABLE(bp))
@@ -2562,19 +2564,23 @@ static int bnxt_set_eee(struct net_device *dev, struct 
ethtool_eee *edata)
        if (!(bp->flags & BNXT_FLAG_EEE_CAP))
                return -EOPNOTSUPP;
 
+       mutex_lock(&bp->link_lock);
+       advertising = _bnxt_fw_to_ethtool_adv_spds(link_info->advertising, 0);
        if (!edata->eee_enabled)
                goto eee_ok;
 
        if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) {
                netdev_warn(dev, "EEE requires autoneg\n");
-               return -EINVAL;
+               rc = -EINVAL;
+               goto eee_exit;
        }
        if (edata->tx_lpi_enabled) {
                if (bp->lpi_tmr_hi && (edata->tx_lpi_timer > bp->lpi_tmr_hi ||
                                       edata->tx_lpi_timer < bp->lpi_tmr_lo)) {
                        netdev_warn(dev, "Valid LPI timer range is %d and %d 
microsecs\n",
                                    bp->lpi_tmr_lo, bp->lpi_tmr_hi);
-                       return -EINVAL;
+                       rc = -EINVAL;
+                       goto eee_exit;
                } else if (!bp->lpi_tmr_hi) {
                        edata->tx_lpi_timer = eee->tx_lpi_timer;
                }
@@ -2584,7 +2590,8 @@ static int bnxt_set_eee(struct net_device *dev, struct 
ethtool_eee *edata)
        } else if (edata->advertised & ~advertising) {
                netdev_warn(dev, "EEE advertised %x must be a subset of autoneg 
advertised speeds %x\n",
                            edata->advertised, advertising);
-               return -EINVAL;
+               rc = -EINVAL;
+               goto eee_exit;
        }
 
        eee->advertised = edata->advertised;
@@ -2596,6 +2603,8 @@ static int bnxt_set_eee(struct net_device *dev, struct 
ethtool_eee *edata)
        if (netif_running(dev))
                rc = bnxt_hwrm_set_link_setting(bp, false, true);
 
+eee_exit:
+       mutex_unlock(&bp->link_lock);
        return rc;
 }
 
-- 
1.8.3.1

Reply via email to