forcedeth bug fix: realtek phy
Subsystems (2)
PATCH 3/3 forcedeth bug fix: realtek phy
This patch contains errata fixes for the realtek phy.
Signed-off-by Ayaz Abdulla <[email protected]>
drivers/net/forcedeth.c +54 -0
@@ -551,6 +551,7 @@#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 @@#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 @@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 @@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);