Skip to content

Commit bef1e4c

Browse files
committed
Merge branch 'bcmgenet-protect-contended-accesses'
Doug Berger says: ==================== net: bcmgenet: protect contended accesses Some registers may be modified by parallel execution contexts and require protections to prevent corruption. A review of the driver revealed the need for these additional protections. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents b2ff42c + 0d5e2a8 commit bef1e4c

File tree

4 files changed

+29
-5
lines changed

4 files changed

+29
-5
lines changed

drivers/net/ethernet/broadcom/genet/bcmgenet.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* Broadcom GENET (Gigabit Ethernet) controller driver
44
*
5-
* Copyright (c) 2014-2020 Broadcom
5+
* Copyright (c) 2014-2024 Broadcom
66
*/
77

88
#define pr_fmt(fmt) "bcmgenet: " fmt
@@ -2467,14 +2467,18 @@ static void umac_enable_set(struct bcmgenet_priv *priv, u32 mask, bool enable)
24672467
{
24682468
u32 reg;
24692469

2470+
spin_lock_bh(&priv->reg_lock);
24702471
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
2471-
if (reg & CMD_SW_RESET)
2472+
if (reg & CMD_SW_RESET) {
2473+
spin_unlock_bh(&priv->reg_lock);
24722474
return;
2475+
}
24732476
if (enable)
24742477
reg |= mask;
24752478
else
24762479
reg &= ~mask;
24772480
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
2481+
spin_unlock_bh(&priv->reg_lock);
24782482

24792483
/* UniMAC stops on a packet boundary, wait for a full-size packet
24802484
* to be processed
@@ -2490,8 +2494,10 @@ static void reset_umac(struct bcmgenet_priv *priv)
24902494
udelay(10);
24912495

24922496
/* issue soft reset and disable MAC while updating its registers */
2497+
spin_lock_bh(&priv->reg_lock);
24932498
bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD);
24942499
udelay(2);
2500+
spin_unlock_bh(&priv->reg_lock);
24952501
}
24962502

24972503
static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
@@ -3334,7 +3340,9 @@ static void bcmgenet_netif_start(struct net_device *dev)
33343340
struct bcmgenet_priv *priv = netdev_priv(dev);
33353341

33363342
/* Start the network engine */
3343+
netif_addr_lock_bh(dev);
33373344
bcmgenet_set_rx_mode(dev);
3345+
netif_addr_unlock_bh(dev);
33383346
bcmgenet_enable_rx_napi(priv);
33393347

33403348
umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true);
@@ -3595,16 +3603,19 @@ static void bcmgenet_set_rx_mode(struct net_device *dev)
35953603
* 3. The number of filters needed exceeds the number filters
35963604
* supported by the hardware.
35973605
*/
3606+
spin_lock(&priv->reg_lock);
35983607
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
35993608
if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) ||
36003609
(nfilter > MAX_MDF_FILTER)) {
36013610
reg |= CMD_PROMISC;
36023611
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
3612+
spin_unlock(&priv->reg_lock);
36033613
bcmgenet_umac_writel(priv, 0, UMAC_MDF_CTRL);
36043614
return;
36053615
} else {
36063616
reg &= ~CMD_PROMISC;
36073617
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
3618+
spin_unlock(&priv->reg_lock);
36083619
}
36093620

36103621
/* update MDF filter */
@@ -4003,6 +4014,7 @@ static int bcmgenet_probe(struct platform_device *pdev)
40034014
goto err;
40044015
}
40054016

4017+
spin_lock_init(&priv->reg_lock);
40064018
spin_lock_init(&priv->lock);
40074019

40084020
/* Set default pause parameters */

drivers/net/ethernet/broadcom/genet/bcmgenet.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* SPDX-License-Identifier: GPL-2.0-only */
22
/*
3-
* Copyright (c) 2014-2020 Broadcom
3+
* Copyright (c) 2014-2024 Broadcom
44
*/
55

66
#ifndef __BCMGENET_H__
@@ -573,6 +573,8 @@ struct bcmgenet_rxnfc_rule {
573573
/* device context */
574574
struct bcmgenet_priv {
575575
void __iomem *base;
576+
/* reg_lock: lock to serialize access to shared registers */
577+
spinlock_t reg_lock;
576578
enum bcmgenet_version version;
577579
struct net_device *dev;
578580

drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support
44
*
5-
* Copyright (c) 2014-2020 Broadcom
5+
* Copyright (c) 2014-2024 Broadcom
66
*/
77

88
#define pr_fmt(fmt) "bcmgenet_wol: " fmt
@@ -151,13 +151,15 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
151151
}
152152

153153
/* Can't suspend with WoL if MAC is still in reset */
154+
spin_lock_bh(&priv->reg_lock);
154155
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
155156
if (reg & CMD_SW_RESET)
156157
reg &= ~CMD_SW_RESET;
157158

158159
/* disable RX */
159160
reg &= ~CMD_RX_EN;
160161
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
162+
spin_unlock_bh(&priv->reg_lock);
161163
mdelay(10);
162164

163165
if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
@@ -203,13 +205,15 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
203205
}
204206

205207
/* Enable CRC forward */
208+
spin_lock_bh(&priv->reg_lock);
206209
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
207210
priv->crc_fwd_en = 1;
208211
reg |= CMD_CRC_FWD;
209212

210213
/* Receiver must be enabled for WOL MP detection */
211214
reg |= CMD_RX_EN;
212215
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
216+
spin_unlock_bh(&priv->reg_lock);
213217

214218
reg = UMAC_IRQ_MPD_R;
215219
if (hfb_enable)
@@ -256,7 +260,9 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
256260
}
257261

258262
/* Disable CRC Forward */
263+
spin_lock_bh(&priv->reg_lock);
259264
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
260265
reg &= ~CMD_CRC_FWD;
261266
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
267+
spin_unlock_bh(&priv->reg_lock);
262268
}

drivers/net/ethernet/broadcom/genet/bcmmii.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* Broadcom GENET MDIO routines
44
*
5-
* Copyright (c) 2014-2017 Broadcom
5+
* Copyright (c) 2014-2024 Broadcom
66
*/
77

88
#include <linux/acpi.h>
@@ -76,6 +76,7 @@ static void bcmgenet_mac_config(struct net_device *dev)
7676
reg |= RGMII_LINK;
7777
bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
7878

79+
spin_lock_bh(&priv->reg_lock);
7980
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
8081
reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) |
8182
CMD_HD_EN |
@@ -88,6 +89,7 @@ static void bcmgenet_mac_config(struct net_device *dev)
8889
reg |= CMD_TX_EN | CMD_RX_EN;
8990
}
9091
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
92+
spin_unlock_bh(&priv->reg_lock);
9193

9294
active = phy_init_eee(phydev, 0) >= 0;
9395
bcmgenet_eee_enable_set(dev,
@@ -275,6 +277,7 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
275277
* block for the interface to work, unconditionally clear the
276278
* Out-of-band disable since we do not need it.
277279
*/
280+
mutex_lock(&phydev->lock);
278281
reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
279282
reg &= ~OOB_DISABLE;
280283
if (priv->ext_phy) {
@@ -286,6 +289,7 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
286289
reg |= RGMII_MODE_EN;
287290
}
288291
bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
292+
mutex_unlock(&phydev->lock);
289293

290294
if (init)
291295
dev_info(kdev, "configuring instance for %s\n", phy_name);

0 commit comments

Comments
 (0)