diff options
| author | Ayaz Abdulla <aabdulla@nvidia.com> | 2007-07-15 06:51:03 -0400 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2007-07-16 18:29:17 -0400 |
| commit | c5e3ae8823693b260ce1f217adca8add1bc0b3de (patch) | |
| tree | d900b91574570a582cb16d958136f8c38abf14a4 | |
| parent | d215d8a269f397d303c3d5f7c74e98592e8284f1 (diff) | |
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>
| -rw-r--r-- | drivers/net/forcedeth.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index f66c521d429d..a361dba5ddaa 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
| @@ -551,6 +551,7 @@ union ring_type { | |||
| 551 | #define PHY_OUI_MARVELL 0x5043 | 551 | #define PHY_OUI_MARVELL 0x5043 |
| 552 | #define PHY_OUI_CICADA 0x03f1 | 552 | #define PHY_OUI_CICADA 0x03f1 |
| 553 | #define PHY_OUI_VITESSE 0x01c1 | 553 | #define PHY_OUI_VITESSE 0x01c1 |
| 554 | #define PHY_OUI_REALTEK 0x01c1 | ||
| 554 | #define PHYID1_OUI_MASK 0x03ff | 555 | #define PHYID1_OUI_MASK 0x03ff |
| 555 | #define PHYID1_OUI_SHFT 6 | 556 | #define PHYID1_OUI_SHFT 6 |
| 556 | #define PHYID2_OUI_MASK 0xfc00 | 557 | #define PHYID2_OUI_MASK 0xfc00 |
| @@ -580,6 +581,13 @@ union ring_type { | |||
| 580 | #define PHY_VITESSE_INIT8 0x0100 | 581 | #define PHY_VITESSE_INIT8 0x0100 |
| 581 | #define PHY_VITESSE_INIT9 0x8f82 | 582 | #define PHY_VITESSE_INIT9 0x8f82 |
| 582 | #define PHY_VITESSE_INIT10 0x0 | 583 | #define PHY_VITESSE_INIT10 0x0 |
| 584 | #define PHY_REALTEK_INIT_REG1 0x1f | ||
| 585 | #define PHY_REALTEK_INIT_REG2 0x19 | ||
| 586 | #define PHY_REALTEK_INIT_REG3 0x13 | ||
| 587 | #define PHY_REALTEK_INIT1 0x0000 | ||
| 588 | #define PHY_REALTEK_INIT2 0x8e00 | ||
| 589 | #define PHY_REALTEK_INIT3 0x0001 | ||
| 590 | #define PHY_REALTEK_INIT4 0xad17 | ||
| 583 | 591 | ||
| 584 | #define PHY_GIGABIT 0x0100 | 592 | #define PHY_GIGABIT 0x0100 |
| 585 | 593 | ||
| @@ -1114,6 +1122,28 @@ static int phy_init(struct net_device *dev) | |||
| 1114 | return PHY_ERROR; | 1122 | return PHY_ERROR; |
| 1115 | } | 1123 | } |
| 1116 | } | 1124 | } |
| 1125 | if (np->phy_oui == PHY_OUI_REALTEK) { | ||
| 1126 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { | ||
| 1127 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1128 | return PHY_ERROR; | ||
| 1129 | } | ||
| 1130 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { | ||
| 1131 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1132 | return PHY_ERROR; | ||
| 1133 | } | ||
| 1134 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { | ||
| 1135 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1136 | return PHY_ERROR; | ||
| 1137 | } | ||
| 1138 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { | ||
| 1139 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1140 | return PHY_ERROR; | ||
| 1141 | } | ||
| 1142 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { | ||
| 1143 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1144 | return PHY_ERROR; | ||
| 1145 | } | ||
| 1146 | } | ||
| 1117 | 1147 | ||
| 1118 | /* set advertise register */ | 1148 | /* set advertise register */ |
| 1119 | reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); | 1149 | reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); |
| @@ -1250,6 +1280,30 @@ static int phy_init(struct net_device *dev) | |||
| 1250 | return PHY_ERROR; | 1280 | return PHY_ERROR; |
| 1251 | } | 1281 | } |
| 1252 | } | 1282 | } |
| 1283 | if (np->phy_oui == PHY_OUI_REALTEK) { | ||
| 1284 | /* reset could have cleared these out, set them back */ | ||
| 1285 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { | ||
| 1286 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1287 | return PHY_ERROR; | ||
| 1288 | } | ||
| 1289 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { | ||
| 1290 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1291 | return PHY_ERROR; | ||
| 1292 | } | ||
| 1293 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { | ||
| 1294 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1295 | return PHY_ERROR; | ||
| 1296 | } | ||
| 1297 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { | ||
| 1298 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1299 | return PHY_ERROR; | ||
| 1300 | } | ||
| 1301 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { | ||
| 1302 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1303 | return PHY_ERROR; | ||
| 1304 | } | ||
| 1305 | } | ||
| 1306 | |||
| 1253 | /* some phys clear out pause advertisment on reset, set it back */ | 1307 | /* some phys clear out pause advertisment on reset, set it back */ |
| 1254 | mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg); | 1308 | mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg); |
| 1255 | 1309 | ||
