Skip to content

Commit 86831a3

Browse files
vladimirolteandavem330
authored andcommitted
net: enetc: remove ERR050089 workaround for i.MX95
The ERR050089 workaround causes performance degradation and potential functional issues (e.g., RCU stalls) under certain workloads. Since new SoCs like i.MX95 do not require this workaround, use a static key to compile out enetc_lock_mdio() and enetc_unlock_mdio() at runtime, improving performance and avoiding unnecessary logic. Signed-off-by: Vladimir Oltean <[email protected]> Signed-off-by: Wei Fang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 3774409 commit 86831a3

File tree

2 files changed

+52
-10
lines changed

2 files changed

+52
-10
lines changed

drivers/net/ethernet/freescale/enetc/enetc_hw.h

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -396,18 +396,22 @@ struct enetc_hw {
396396
*/
397397
extern rwlock_t enetc_mdio_lock;
398398

399+
DECLARE_STATIC_KEY_FALSE(enetc_has_err050089);
400+
399401
/* use this locking primitive only on the fast datapath to
400402
* group together multiple non-MDIO register accesses to
401403
* minimize the overhead of the lock
402404
*/
403405
static inline void enetc_lock_mdio(void)
404406
{
405-
read_lock(&enetc_mdio_lock);
407+
if (static_branch_unlikely(&enetc_has_err050089))
408+
read_lock(&enetc_mdio_lock);
406409
}
407410

408411
static inline void enetc_unlock_mdio(void)
409412
{
410-
read_unlock(&enetc_mdio_lock);
413+
if (static_branch_unlikely(&enetc_has_err050089))
414+
read_unlock(&enetc_mdio_lock);
411415
}
412416

413417
/* use these accessors only on the fast datapath under
@@ -416,14 +420,16 @@ static inline void enetc_unlock_mdio(void)
416420
*/
417421
static inline u32 enetc_rd_reg_hot(void __iomem *reg)
418422
{
419-
lockdep_assert_held(&enetc_mdio_lock);
423+
if (static_branch_unlikely(&enetc_has_err050089))
424+
lockdep_assert_held(&enetc_mdio_lock);
420425

421426
return ioread32(reg);
422427
}
423428

424429
static inline void enetc_wr_reg_hot(void __iomem *reg, u32 val)
425430
{
426-
lockdep_assert_held(&enetc_mdio_lock);
431+
if (static_branch_unlikely(&enetc_has_err050089))
432+
lockdep_assert_held(&enetc_mdio_lock);
427433

428434
iowrite32(val, reg);
429435
}
@@ -452,9 +458,13 @@ static inline u32 _enetc_rd_mdio_reg_wa(void __iomem *reg)
452458
unsigned long flags;
453459
u32 val;
454460

455-
write_lock_irqsave(&enetc_mdio_lock, flags);
456-
val = ioread32(reg);
457-
write_unlock_irqrestore(&enetc_mdio_lock, flags);
461+
if (static_branch_unlikely(&enetc_has_err050089)) {
462+
write_lock_irqsave(&enetc_mdio_lock, flags);
463+
val = ioread32(reg);
464+
write_unlock_irqrestore(&enetc_mdio_lock, flags);
465+
} else {
466+
val = ioread32(reg);
467+
}
458468

459469
return val;
460470
}
@@ -463,9 +473,13 @@ static inline void _enetc_wr_mdio_reg_wa(void __iomem *reg, u32 val)
463473
{
464474
unsigned long flags;
465475

466-
write_lock_irqsave(&enetc_mdio_lock, flags);
467-
iowrite32(val, reg);
468-
write_unlock_irqrestore(&enetc_mdio_lock, flags);
476+
if (static_branch_unlikely(&enetc_has_err050089)) {
477+
write_lock_irqsave(&enetc_mdio_lock, flags);
478+
iowrite32(val, reg);
479+
write_unlock_irqrestore(&enetc_mdio_lock, flags);
480+
} else {
481+
iowrite32(val, reg);
482+
}
469483
}
470484

471485
#ifdef ioread64

drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,28 @@
99
#define ENETC_MDIO_BUS_NAME ENETC_MDIO_DEV_NAME " Bus"
1010
#define ENETC_MDIO_DRV_NAME ENETC_MDIO_DEV_NAME " driver"
1111

12+
DEFINE_STATIC_KEY_FALSE(enetc_has_err050089);
13+
EXPORT_SYMBOL_GPL(enetc_has_err050089);
14+
15+
static void enetc_emdio_enable_err050089(struct pci_dev *pdev)
16+
{
17+
if (pdev->vendor == PCI_VENDOR_ID_FREESCALE &&
18+
pdev->device == ENETC_MDIO_DEV_ID) {
19+
static_branch_inc(&enetc_has_err050089);
20+
dev_info(&pdev->dev, "Enabled ERR050089 workaround\n");
21+
}
22+
}
23+
24+
static void enetc_emdio_disable_err050089(struct pci_dev *pdev)
25+
{
26+
if (pdev->vendor == PCI_VENDOR_ID_FREESCALE &&
27+
pdev->device == ENETC_MDIO_DEV_ID) {
28+
static_branch_dec(&enetc_has_err050089);
29+
if (!static_key_enabled(&enetc_has_err050089.key))
30+
dev_info(&pdev->dev, "Disabled ERR050089 workaround\n");
31+
}
32+
}
33+
1234
static int enetc_pci_mdio_probe(struct pci_dev *pdev,
1335
const struct pci_device_id *ent)
1436
{
@@ -62,6 +84,8 @@ static int enetc_pci_mdio_probe(struct pci_dev *pdev,
6284
goto err_pci_mem_reg;
6385
}
6486

87+
enetc_emdio_enable_err050089(pdev);
88+
6589
err = of_mdiobus_register(bus, dev->of_node);
6690
if (err)
6791
goto err_mdiobus_reg;
@@ -71,6 +95,7 @@ static int enetc_pci_mdio_probe(struct pci_dev *pdev,
7195
return 0;
7296

7397
err_mdiobus_reg:
98+
enetc_emdio_disable_err050089(pdev);
7499
pci_release_region(pdev, 0);
75100
err_pci_mem_reg:
76101
pci_disable_device(pdev);
@@ -88,6 +113,9 @@ static void enetc_pci_mdio_remove(struct pci_dev *pdev)
88113
struct enetc_mdio_priv *mdio_priv;
89114

90115
mdiobus_unregister(bus);
116+
117+
enetc_emdio_disable_err050089(pdev);
118+
91119
mdio_priv = bus->priv;
92120
iounmap(mdio_priv->hw->port);
93121
pci_release_region(pdev, 0);

0 commit comments

Comments
 (0)