From f6bba9549012eb31bd877994ed5f8a912b08d0ed Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Wed, 16 Feb 2011 00:58:40 +0800 Subject: [PATCH] jme: Reinit PHY processor after each PHY power on Re-initialize PHY processor right after each PHY power on. To make sure no required status was massed up while power off. --- jme.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ jme.h | 17 +++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/jme.c b/jme.c index ce5ebc5..aeedfe2 100644 --- a/jme.c +++ b/jme.c @@ -1772,6 +1772,69 @@ jme_new_phy_off(struct jme_adapter *jme) pci_write_config_dword(jme->pdev, PCI_PRIV_PE1, reg); } +static inline void +jme_recal_phy(struct jme_adapter *jme) +{ + u32 miictl1000, comm2; + + miictl1000 = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_CTRL1000); + miictl1000 &= ~JME_PHY_GCTRL_TESTMASK; + miictl1000 |= JME_PHY_GCTRL_TESTMODE1; + jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_CTRL1000, miictl1000); + + comm2 = jme_phyext_read(jme, JME_PHYEXT_COMM2); + comm2 &= ~(0x0001u); + comm2 |= 0x0011u; + jme_phyext_write(jme, JME_PHYEXT_COMM2, comm2); + + mdelay(20); + + comm2 = jme_phyext_read(jme, JME_PHYEXT_COMM2); + comm2 &= ~(0x0013u); + jme_phyext_write(jme, JME_PHYEXT_COMM2, comm2); + + miictl1000 = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_CTRL1000); + miictl1000 &= ~JME_PHY_GCTRL_TESTMASK; + jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_CTRL1000, miictl1000); +} + +static inline void +jme_set_phyparm(struct jme_adapter *jme, u32 val) +{ + u32 comm0, comm1; + + comm0 = jme_phyext_read(jme, JME_PHYEXT_COMM0); + comm1 = jme_phyext_read(jme, JME_PHYEXT_COMM1); + comm0 &= ~(0xE000u); + comm0 |= ((val << 13) & 0xE000u); + comm1 &= ~(0x0001u); + comm1 |= ((val >> 3) & 0x0001u); + jme_phyext_write(jme, JME_PHYEXT_COMM0, comm0); + jme_phyext_write(jme, JME_PHYEXT_COMM1, comm1); +} + +static inline void +jme_refill_phyparm(struct jme_adapter *jme) +{ + if (jme->chip_main_rev >= 6 || + (jme->chip_main_rev == 5 && + (jme->chip_sub_rev == 0 || + jme->chip_sub_rev == 1 || + jme->chip_sub_rev == 3))) { + jme_set_phyparm(jme, 0x8); + } else if (jme->chip_main_rev == 3 && + (jme->chip_sub_rev == 1 || + jme->chip_sub_rev == 2)) { + jme_set_phyparm(jme, 0x7); + } else if (jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC260 && + jme->chip_main_rev == 2) { + if (jme->chip_sub_rev == 0) + jme_set_phyparm(jme, 0x3); + else if (jme->chip_sub_rev == 2) + jme_set_phyparm(jme, 0x2); + } +} + static inline void jme_phy_on(struct jme_adapter *jme) { @@ -1783,6 +1846,9 @@ jme_phy_on(struct jme_adapter *jme) bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); bmcr &= ~BMCR_PDOWN; jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr); + + jme_recal_phy(jme); + jme_refill_phyparm(jme); } static inline void diff --git a/jme.h b/jme.h index c27a342..1f65208 100644 --- a/jme.h +++ b/jme.h @@ -1379,6 +1379,18 @@ enum jme_phy_reg17_vals { PREG17_SPEED_1000M = 0x8000, }; +enum jme_phy_gctrl_masks { + JME_PHY_GCTRL_TESTMASK = 0xA000, +}; + +enum jme_phy_gctrl_vals { + JME_PHY_GCTRL_TESTOFF = 0x0000, + JME_PHY_GCTRL_TESTMODE1 = 0x2000, + JME_PHY_GCTRL_TESTMODE2 = 0x4000, + JME_PHY_GCTRL_TESTMODE3 = 0x6000, + JME_PHY_GCTRL_TESTMODE4 = 0x8000, +}; + #define BMSR_ANCOMP 0x0020 /* @@ -1392,6 +1404,11 @@ enum jme_phy_spec_addr_bits { JME_PHY_SPEC_REG_READ = 0x4000u, JME_PHY_SPEC_REG_WRITE = 0x8000u, }; +enum jme_extphy_regs { + JME_PHYEXT_COMM0 = 0x30, + JME_PHYEXT_COMM1 = 0x31, + JME_PHYEXT_COMM2 = 0x32, +}; /* * Workaround -- 2.39.3