Skip to content

Commit c44d3ff

Browse files
Raju LakkarajuPaolo Abeni
authored andcommitted
net: phy: mxl-gpy: Remove interrupt mask clearing from config_init
When the system resumes from sleep, the phy_init_hw() function invokes config_init(), which clears all interrupt masks and causes wake events to be lost in subsequent wake sequences. Remove interrupt mask clearing from config_init() and preserve relevant masks in config_intr(). Fixes: 7d901a1 ("net: phy: add Maxlinear GPY115/21x/24x driver") Reviewed-by: Wojciech Drewek <[email protected]> Signed-off-by: Raju Lakkaraju <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 8c248cd commit c44d3ff

File tree

1 file changed

+38
-20
lines changed

1 file changed

+38
-20
lines changed

drivers/net/phy/mxl-gpy.c

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ struct gpy_priv {
107107

108108
u8 fw_major;
109109
u8 fw_minor;
110+
u32 wolopts;
110111

111112
/* It takes 3 seconds to fully switch out of loopback mode before
112113
* it can safely re-enter loopback mode. Record the time when
@@ -221,6 +222,15 @@ static int gpy_hwmon_register(struct phy_device *phydev)
221222
}
222223
#endif
223224

225+
static int gpy_ack_interrupt(struct phy_device *phydev)
226+
{
227+
int ret;
228+
229+
/* Clear all pending interrupts */
230+
ret = phy_read(phydev, PHY_ISTAT);
231+
return ret < 0 ? ret : 0;
232+
}
233+
224234
static int gpy_mbox_read(struct phy_device *phydev, u32 addr)
225235
{
226236
struct gpy_priv *priv = phydev->priv;
@@ -262,16 +272,8 @@ static int gpy_mbox_read(struct phy_device *phydev, u32 addr)
262272

263273
static int gpy_config_init(struct phy_device *phydev)
264274
{
265-
int ret;
266-
267-
/* Mask all interrupts */
268-
ret = phy_write(phydev, PHY_IMASK, 0);
269-
if (ret)
270-
return ret;
271-
272-
/* Clear all pending interrupts */
273-
ret = phy_read(phydev, PHY_ISTAT);
274-
return ret < 0 ? ret : 0;
275+
/* Nothing to configure. Configuration Requirement Placeholder */
276+
return 0;
275277
}
276278

277279
static int gpy21x_config_init(struct phy_device *phydev)
@@ -627,11 +629,23 @@ static int gpy_read_status(struct phy_device *phydev)
627629

628630
static int gpy_config_intr(struct phy_device *phydev)
629631
{
632+
struct gpy_priv *priv = phydev->priv;
630633
u16 mask = 0;
634+
int ret;
635+
636+
ret = gpy_ack_interrupt(phydev);
637+
if (ret)
638+
return ret;
631639

632640
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
633641
mask = PHY_IMASK_MASK;
634642

643+
if (priv->wolopts & WAKE_MAGIC)
644+
mask |= PHY_IMASK_WOL;
645+
646+
if (priv->wolopts & WAKE_PHY)
647+
mask |= PHY_IMASK_LSTC;
648+
635649
return phy_write(phydev, PHY_IMASK, mask);
636650
}
637651

@@ -678,6 +692,7 @@ static int gpy_set_wol(struct phy_device *phydev,
678692
struct ethtool_wolinfo *wol)
679693
{
680694
struct net_device *attach_dev = phydev->attached_dev;
695+
struct gpy_priv *priv = phydev->priv;
681696
int ret;
682697

683698
if (wol->wolopts & WAKE_MAGIC) {
@@ -725,13 +740,22 @@ static int gpy_set_wol(struct phy_device *phydev,
725740
ret = phy_read(phydev, PHY_ISTAT);
726741
if (ret < 0)
727742
return ret;
743+
744+
priv->wolopts |= WAKE_MAGIC;
728745
} else {
729746
/* Disable magic packet matching */
730747
ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2,
731748
VPSPEC2_WOL_CTL,
732749
WOL_EN);
733750
if (ret < 0)
734751
return ret;
752+
753+
/* Disable the WOL interrupt */
754+
ret = phy_clear_bits(phydev, PHY_IMASK, PHY_IMASK_WOL);
755+
if (ret < 0)
756+
return ret;
757+
758+
priv->wolopts &= ~WAKE_MAGIC;
735759
}
736760

737761
if (wol->wolopts & WAKE_PHY) {
@@ -748,28 +772,22 @@ static int gpy_set_wol(struct phy_device *phydev,
748772
if (ret & (PHY_IMASK_MASK & ~PHY_IMASK_LSTC))
749773
phy_trigger_machine(phydev);
750774

775+
priv->wolopts |= WAKE_PHY;
751776
return 0;
752777
}
753778

779+
priv->wolopts &= ~WAKE_PHY;
754780
/* Disable the link state change interrupt */
755781
return phy_clear_bits(phydev, PHY_IMASK, PHY_IMASK_LSTC);
756782
}
757783

758784
static void gpy_get_wol(struct phy_device *phydev,
759785
struct ethtool_wolinfo *wol)
760786
{
761-
int ret;
787+
struct gpy_priv *priv = phydev->priv;
762788

763789
wol->supported = WAKE_MAGIC | WAKE_PHY;
764-
wol->wolopts = 0;
765-
766-
ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, VPSPEC2_WOL_CTL);
767-
if (ret & WOL_EN)
768-
wol->wolopts |= WAKE_MAGIC;
769-
770-
ret = phy_read(phydev, PHY_IMASK);
771-
if (ret & PHY_IMASK_LSTC)
772-
wol->wolopts |= WAKE_PHY;
790+
wol->wolopts = priv->wolopts;
773791
}
774792

775793
static int gpy_loopback(struct phy_device *phydev, bool enable)

0 commit comments

Comments
 (0)