forcedeth bug fix: realtek phy
This patch contains errata fixes for the realtek phy. Signed-off-by: Ayaz Abdulla <aabdulla@nvidia.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
d215d8a269
commit
c5e3ae8823
1 changed files with 54 additions and 0 deletions
|
@ -551,6 +551,7 @@ union ring_type {
|
|||
#define PHY_OUI_MARVELL 0x5043
|
||||
#define PHY_OUI_CICADA 0x03f1
|
||||
#define PHY_OUI_VITESSE 0x01c1
|
||||
#define PHY_OUI_REALTEK 0x01c1
|
||||
#define PHYID1_OUI_MASK 0x03ff
|
||||
#define PHYID1_OUI_SHFT 6
|
||||
#define PHYID2_OUI_MASK 0xfc00
|
||||
|
@ -580,6 +581,13 @@ union ring_type {
|
|||
#define PHY_VITESSE_INIT8 0x0100
|
||||
#define PHY_VITESSE_INIT9 0x8f82
|
||||
#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
|
||||
|
||||
|
@ -1114,6 +1122,28 @@ static int phy_init(struct net_device *dev)
|
|||
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 */
|
||||
reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
|
||||
|
@ -1250,6 +1280,30 @@ static int phy_init(struct net_device *dev)
|
|||
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 */
|
||||
mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg);
|
||||
|
||||
|
|
Loading…
Reference in a new issue