Skip to content

Commit bc8ca58

Browse files
ffainelliKelsey Skunberg
authored andcommitted
r6040: Restore MDIO clock frequency after MAC reset
BugLink: https://bugs.launchpad.net/bugs/1946802 commit e3f0cc1 upstream. A number of users have reported that they were not able to get the PHY to successfully link up, especially after commit c36757e ("net: phy: consider AN_RESTART status when reading link status") where we stopped reading just BMSR, but we also read BMCR to determine the link status. Andrius at NetBSD did a wonderful job at debugging the problem and found out that the MDIO bus clock frequency would be incorrectly set back to its default value which would prevent the MDIO bus controller from reading PHY registers properly. Back when we only read BMSR, if we read all 1s, we could falsely indicate a link status, though in general there is a cable plugged in, so this went unnoticed. After a second read of BMCR was added, a wrong read will lead to the inability to determine a link UP condition which is when it started to be visibly broken, even if it was long before that. The fix consists in restoring the value of the MD_CSR register that was set prior to the MAC reset. Link: http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=53494 Fixes: 90f750a ("r6040: consolidate MAC reset to its own function") Reported-by: Andrius V <vezhlys@gmail.com> Reported-by: Darek Strugacz <darek.strugacz@op.pl> Tested-by: Darek Strugacz <darek.strugacz@op.pl> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Kamal Mostafa <kamal@canonical.com> Signed-off-by: Kelsey Skunberg <kelsey.skunberg@canonical.com>
1 parent 58f6673 commit bc8ca58

1 file changed

Lines changed: 8 additions & 1 deletion

File tree

drivers/net/ethernet/rdc/r6040.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@
119119
#define PHY_ST 0x8A /* PHY status register */
120120
#define MAC_SM 0xAC /* MAC status machine */
121121
#define MAC_SM_RST 0x0002 /* MAC status machine reset */
122+
#define MD_CSC 0xb6 /* MDC speed control register */
123+
#define MD_CSC_DEFAULT 0x0030
122124
#define MAC_ID 0xBE /* Identifier register */
123125

124126
#define TX_DCNT 0x80 /* TX descriptor count */
@@ -354,8 +356,9 @@ static void r6040_reset_mac(struct r6040_private *lp)
354356
{
355357
void __iomem *ioaddr = lp->base;
356358
int limit = MAC_DEF_TIMEOUT;
357-
u16 cmd;
359+
u16 cmd, md_csc;
358360

361+
md_csc = ioread16(ioaddr + MD_CSC);
359362
iowrite16(MAC_RST, ioaddr + MCR1);
360363
while (limit--) {
361364
cmd = ioread16(ioaddr + MCR1);
@@ -367,6 +370,10 @@ static void r6040_reset_mac(struct r6040_private *lp)
367370
iowrite16(MAC_SM_RST, ioaddr + MAC_SM);
368371
iowrite16(0, ioaddr + MAC_SM);
369372
mdelay(5);
373+
374+
/* Restore MDIO clock frequency */
375+
if (md_csc != MD_CSC_DEFAULT)
376+
iowrite16(md_csc, ioaddr + MD_CSC);
370377
}
371378

372379
static void r6040_init_mac_regs(struct net_device *dev)

0 commit comments

Comments
 (0)