--- old/drivers/net/forcedeth.c 2009-08-31 19:01:04.000000000 -0400 +++ new/drivers/net/forcedeth.c 2009-08-31 19:05:49.000000000 -0400 @@ -506,6 +506,7 @@ #define PHY_OUI_VITESSE 0x01c1 #define PHY_OUI_REALTEK 0x0732 #define PHY_OUI_REALTEK2 0x0020 +#define PHY_OUI_BROADCOM 0x50ef #define PHYID1_OUI_MASK 0x03ff #define PHYID1_OUI_SHFT 6 #define PHYID2_OUI_MASK 0xfc00 @@ -517,7 +518,18 @@ #define PHY_REV_REALTEK_8211C 0x0001 #define PHY_MODEL_REALTEK_8201 0x0200 #define PHY_MODEL_MARVELL_E3016 0x0220 -#define PHY_MARVELL_E3016_INITMASK 0x0300 +#define PHY_MODEL_MARVELL_E1116 0x0210 +#define PHY_MODEL_MARVELL_E1111 0x00c0 +#define PHY_MODEL_MARVELL_E1011 0x00b0 +#define PHY_MODEL_BROADCOM_9507 0x00a0 +#define PHY_MODEL_BROADCOM_AC131 0x0070 +#define PHY_MODEL_BROADCOM_50610 0x0160 +#define PHY_MARVELL_INIT_REG1 0x16 +#define PHY_MARVELL_INIT_REG2 0x10 +#define PHY_MARVELL_INIT1 0x0300 +#define PHY_MARVELL_INIT2 0x4000 +#define PHY_MARVELL_INIT_MSK1 0x0300 +#define PHY_MARVELL_INIT_MSK2 0x00ff #define PHY_CICADA_INIT1 0x0f000 #define PHY_CICADA_INIT2 0x0e00 #define PHY_CICADA_INIT3 0x01000 @@ -559,6 +571,19 @@ #define PHY_REALTEK_INIT10 0x0005 #define PHY_REALTEK_INIT11 0x0200 #define PHY_REALTEK_INIT_MSK1 0x0003 +#define PHY_BROADCOM_INIT_REG1 0x1c +#define PHY_BROADCOM_INIT_REG2 0x1f +#define PHY_BROADCOM_INIT_REG3 0x1b +#define PHY_BROADCOM_INIT_REG4 0x17 +#define PHY_BROADCOM_INIT_REG5 0x15 +#define PHY_BROADCOM_INIT1 0x2820 +#define PHY_BROADCOM_INIT2 0x0080 +#define PHY_BROADCOM_INIT3 0x0020 +#define PHY_BROADCOM_INIT4 0x8c00 +#define PHY_BROADCOM_INIT5 0x0f08 +#define PHY_BROADCOM_INIT6 0x0001 +#define PHY_BROADCOM_INIT7 0x0f00 +#define PHY_BROADCOM_INIT_MSK1 0x7c20 #define PHY_GIGABIT 0x0100 @@ -1198,13 +1223,14 @@ u8 __iomem *base = get_hwbase(dev); u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000,reg; - /* phy errata for E3016 phy */ - if (np->phy_model == PHY_MODEL_MARVELL_E3016) { - reg = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); - reg &= ~PHY_MARVELL_E3016_INITMASK; - if (mii_rw(dev, np->phyaddr, MII_NCONFIG, reg)) { - printk(KERN_INFO "%s: phy write to errata reg failed.\n", pci_name(np->pci_dev)); - return PHY_ERROR; + if (np->phy_oui == PHY_OUI_MARVELL) { + if (np->phy_model == PHY_MODEL_MARVELL_E3016) { + reg = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); + reg &= ~PHY_MARVELL_INIT_MSK1; + if (mii_rw(dev, np->phyaddr, MII_NCONFIG, reg)) { + printk(KERN_INFO "%s: phy write to errata reg failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } } } if (np->phy_oui == PHY_OUI_REALTEK) { @@ -1340,6 +1366,89 @@ } /* phy vendor specific configuration */ + if (np->phy_oui == PHY_OUI_MARVELL) { + if (np->driver_data & DEV_NEED_PHY_INIT_FIX) { + if (np->phy_model == PHY_MODEL_MARVELL_E1116) { + phy_reserved = mii_rw(dev, np->phyaddr, PHY_MARVELL_INIT_REG1, MII_READ); + phy_reserved &= ~PHY_MARVELL_INIT_MSK2; + if (mii_rw(dev, np->phyaddr, PHY_MARVELL_INIT_REG1,phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + + phy_reserved = mii_rw(dev, np->phyaddr, PHY_MARVELL_INIT_REG2, MII_READ); + phy_reserved |= PHY_MARVELL_INIT1; + if (mii_rw(dev, np->phyaddr, PHY_MARVELL_INIT_REG2 ,phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + if (np->phy_model == PHY_MODEL_MARVELL_E1111) { + phy_reserved = mii_rw(dev, np->phyaddr, PHY_MARVELL_INIT_REG2, MII_READ); + phy_reserved |= PHY_MARVELL_INIT1; + if (mii_rw(dev, np->phyaddr, PHY_MARVELL_INIT_REG2 ,phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + if (np->phy_model == PHY_MODEL_MARVELL_E3016) { + phy_reserved = mii_rw(dev, np->phyaddr, PHY_MARVELL_INIT_REG2, MII_READ); + phy_reserved |= PHY_MARVELL_INIT2; + if (mii_rw(dev, np->phyaddr, PHY_MARVELL_INIT_REG2 ,phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + } + } + + if (np->phy_oui == PHY_OUI_BROADCOM) { + if (np->driver_data & DEV_NEED_PHY_INIT_FIX) { + if (np->phy_model == PHY_MODEL_BROADCOM_9507) { + phy_reserved = mii_rw(dev, np->phyaddr, PHY_BROADCOM_INIT_REG1, MII_READ); + phy_reserved &= ~PHY_BROADCOM_INIT_MSK1; + phy_reserved |= PHY_BROADCOM_INIT1; + if (mii_rw(dev, np->phyaddr, PHY_BROADCOM_INIT_REG1 ,phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + if (np->phy_model == PHY_MODEL_BROADCOM_AC131) { + phy_reserved = mii_rw(dev, np->phyaddr, PHY_BROADCOM_INIT_REG2, MII_READ); + phy_reserved |= PHY_BROADCOM_INIT2; + if (mii_rw(dev, np->phyaddr, PHY_BROADCOM_INIT_REG2 ,phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + + phy_reserved = mii_rw(dev, np->phyaddr, PHY_BROADCOM_INIT_REG3, MII_READ); + phy_reserved |= PHY_BROADCOM_INIT3; + if (mii_rw(dev, np->phyaddr, PHY_BROADCOM_INIT_REG3 ,phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + } + if (np->phy_model == PHY_MODEL_BROADCOM_50610) { + if (mii_rw(dev, np->phyaddr, PHY_BROADCOM_INIT_REG1, PHY_BROADCOM_INIT4)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_BROADCOM_INIT_REG4, PHY_BROADCOM_INIT5)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_BROADCOM_INIT_REG5, PHY_BROADCOM_INIT6)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_BROADCOM_INIT_REG4, PHY_BROADCOM_INIT7)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + } + if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) { phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ); phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2);