Commit c5e3ae88 authored by Ayaz Abdulla's avatar Ayaz Abdulla Committed by Jeff Garzik

forcedeth bug fix: realtek phy

This patch contains errata fixes for the realtek phy.
Signed-off-by: default avatarAyaz Abdulla <aabdulla@nvidia.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent d215d8a2
...@@ -551,6 +551,7 @@ union ring_type { ...@@ -551,6 +551,7 @@ union ring_type {
#define PHY_OUI_MARVELL 0x5043 #define PHY_OUI_MARVELL 0x5043
#define PHY_OUI_CICADA 0x03f1 #define PHY_OUI_CICADA 0x03f1
#define PHY_OUI_VITESSE 0x01c1 #define PHY_OUI_VITESSE 0x01c1
#define PHY_OUI_REALTEK 0x01c1
#define PHYID1_OUI_MASK 0x03ff #define PHYID1_OUI_MASK 0x03ff
#define PHYID1_OUI_SHFT 6 #define PHYID1_OUI_SHFT 6
#define PHYID2_OUI_MASK 0xfc00 #define PHYID2_OUI_MASK 0xfc00
...@@ -580,6 +581,13 @@ union ring_type { ...@@ -580,6 +581,13 @@ union ring_type {
#define PHY_VITESSE_INIT8 0x0100 #define PHY_VITESSE_INIT8 0x0100
#define PHY_VITESSE_INIT9 0x8f82 #define PHY_VITESSE_INIT9 0x8f82
#define PHY_VITESSE_INIT10 0x0 #define PHY_VITESSE_INIT10 0x0
#define PHY_REALTEK_INIT_REG1 0x1f
#define PHY_REALTEK_INIT_REG2 0x19
#define PHY_REALTEK_INIT_REG3 0x13
#define PHY_REALTEK_INIT1 0x0000
#define PHY_REALTEK_INIT2 0x8e00
#define PHY_REALTEK_INIT3 0x0001
#define PHY_REALTEK_INIT4 0xad17
#define PHY_GIGABIT 0x0100 #define PHY_GIGABIT 0x0100
...@@ -1114,6 +1122,28 @@ static int phy_init(struct net_device *dev) ...@@ -1114,6 +1122,28 @@ static int phy_init(struct net_device *dev)
return PHY_ERROR; return PHY_ERROR;
} }
} }
if (np->phy_oui == PHY_OUI_REALTEK) {
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
}
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
}
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
}
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
}
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
}
}
/* set advertise register */ /* set advertise register */
reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
...@@ -1250,6 +1280,30 @@ static int phy_init(struct net_device *dev) ...@@ -1250,6 +1280,30 @@ static int phy_init(struct net_device *dev)
return PHY_ERROR; return PHY_ERROR;
} }
} }
if (np->phy_oui == PHY_OUI_REALTEK) {
/* reset could have cleared these out, set them back */
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
}
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
}
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
}
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
}
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
}
}
/* some phys clear out pause advertisment on reset, set it back */ /* some phys clear out pause advertisment on reset, set it back */
mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg); mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment