| From stable-bounces@linux.kernel.org Mon Jul 16 15:38:04 2007 |
| From: Ayaz Abdulla <aabdulla@nvidia.com> |
| Date: Mon, 16 Jul 2007 09:50:24 -0400 |
| Subject: forcedeth bug fix: realtek phy |
| To: stable@kernel.org |
| Message-ID: <469B77A0.7080206@nvidia.com> |
| |
| From: Ayaz Abdulla <aabdulla@nvidia.com> |
| |
| This patch contains errata fixes for the realtek phy. It only renamed the |
| defines to be phy specific. |
| |
| Signed-off-by: Ayaz Abdulla <aabdulla@nvidia.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/net/forcedeth.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ |
| 1 file changed, 54 insertions(+) |
| |
| --- a/drivers/net/forcedeth.c |
| +++ b/drivers/net/forcedeth.c |
| @@ -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 *d |
| 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 *d |
| 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); |
| |