X-Git-Url: http://bbs.cooldavid.org/git/?p=jme.git;a=blobdiff_plain;f=jme.c;h=3ebfd490ec13f2cfbf5f1ad1fd777bde06ebad74;hp=89c1ab7dd6f71df41b154ff65d44f2a2c22068d2;hb=44d4458964df5c12bf527b8b3b17eda4c098d54e;hpb=55d197994cdde062c81298badde27b4ccc7907c7 diff --git a/jme.c b/jme.c index 89c1ab7..3ebfd49 100644 --- a/jme.c +++ b/jme.c @@ -163,6 +163,67 @@ jme_setup_wakeup_frame(struct jme_adapter *jme, } } +static inline void +jme_mac_rxclk_off(struct jme_adapter *jme) +{ + jme->reg_gpreg1 |= GPREG1_RXCLKOFF; + jwrite32f(jme, JME_GPREG1, jme->reg_gpreg1); +} + +static inline void +jme_mac_rxclk_on(struct jme_adapter *jme) +{ + jme->reg_gpreg1 &= ~GPREG1_RXCLKOFF; + jwrite32f(jme, JME_GPREG1, jme->reg_gpreg1); +} + +static inline void +jme_mac_txclk_off(struct jme_adapter *jme) +{ + jme->reg_ghc &= ~(GHC_TO_CLK_SRC | GHC_TXMAC_CLK_SRC); + jwrite32f(jme, JME_GHC, jme->reg_ghc); +} + +static inline void +jme_mac_txclk_on(struct jme_adapter *jme) +{ + u32 speed = jme->reg_ghc & GHC_SPEED; + if (speed == GHC_SPEED_1000M) + jme->reg_ghc |= GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY; + else + jme->reg_ghc |= GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE; + jwrite32f(jme, JME_GHC, jme->reg_ghc); +} + +static inline void +jme_reset_ghc_speed(struct jme_adapter *jme) +{ + jme->reg_ghc &= ~(GHC_SPEED | GHC_DPX); + jwrite32f(jme, JME_GHC, jme->reg_ghc); +} + +static inline void +jme_reset_250A2_workaround(struct jme_adapter *jme) +{ + jme->reg_gpreg1 &= ~(GPREG1_HALFMODEPATCH | + GPREG1_RSSPATCH); + jwrite32(jme, JME_GPREG1, jme->reg_gpreg1); +} + +static inline void +jme_assert_ghc_reset(struct jme_adapter *jme) +{ + jme->reg_ghc |= GHC_SWRST; + jwrite32f(jme, JME_GHC, jme->reg_ghc); +} + +static inline void +jme_clear_ghc_reset(struct jme_adapter *jme) +{ + jme->reg_ghc &= ~GHC_SWRST; + jwrite32f(jme, JME_GHC, jme->reg_ghc); +} + static inline void jme_reset_mac_processor(struct jme_adapter *jme) { @@ -171,9 +232,24 @@ jme_reset_mac_processor(struct jme_adapter *jme) u32 gpreg0; int i; - jwrite32(jme, JME_GHC, jme->reg_ghc | GHC_SWRST); - udelay(2); - jwrite32(jme, JME_GHC, jme->reg_ghc); + jme_reset_ghc_speed(jme); + jme_reset_250A2_workaround(jme); + + jme_mac_rxclk_on(jme); + jme_mac_txclk_on(jme); + udelay(1); + jme_assert_ghc_reset(jme); + udelay(1); + jme_mac_rxclk_off(jme); + jme_mac_txclk_off(jme); + udelay(1); + jme_clear_ghc_reset(jme); + udelay(1); + jme_mac_rxclk_on(jme); + jme_mac_txclk_on(jme); + udelay(1); + jme_mac_rxclk_off(jme); + jme_mac_txclk_off(jme); jwrite32(jme, JME_RXDBA_LO, 0x00000000); jwrite32(jme, JME_RXDBA_HI, 0x00000000); @@ -193,14 +269,6 @@ jme_reset_mac_processor(struct jme_adapter *jme) else gpreg0 = GPREG0_DEFAULT; jwrite32(jme, JME_GPREG0, gpreg0); - jwrite32(jme, JME_GPREG1, GPREG1_DEFAULT); -} - -static inline void -jme_reset_ghc_speed(struct jme_adapter *jme) -{ - jme->reg_ghc &= ~(GHC_SPEED_1000M | GHC_DPX); - jwrite32(jme, JME_GHC, jme->reg_ghc); } static inline void @@ -354,7 +422,7 @@ static int jme_check_link(struct net_device *netdev, int testonly) { struct jme_adapter *jme = netdev_priv(netdev); - u32 phylink, ghc, cnt = JME_SPDRSV_TIMEOUT, bmcr, gpreg1; + u32 phylink, cnt = JME_SPDRSV_TIMEOUT, bmcr; char linkmsg[64]; int rc = 0; @@ -417,23 +485,21 @@ jme_check_link(struct net_device *netdev, int testonly) jme->phylink = phylink; - ghc = jme->reg_ghc & ~(GHC_SPEED | GHC_DPX | - GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE | - GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY); + /* + * The speed/duplex setting of jme->reg_ghc already cleared + * by jme_reset_mac_processor() + */ switch (phylink & PHY_LINK_SPEED_MASK) { case PHY_LINK_SPEED_10M: - ghc |= GHC_SPEED_10M | - GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE; + jme->reg_ghc |= GHC_SPEED_10M; strcat(linkmsg, "10 Mbps, "); break; case PHY_LINK_SPEED_100M: - ghc |= GHC_SPEED_100M | - GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE; + jme->reg_ghc |= GHC_SPEED_100M; strcat(linkmsg, "100 Mbps, "); break; case PHY_LINK_SPEED_1000M: - ghc |= GHC_SPEED_1000M | - GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY; + jme->reg_ghc |= GHC_SPEED_1000M; strcat(linkmsg, "1000 Mbps, "); break; default: @@ -442,30 +508,31 @@ jme_check_link(struct net_device *netdev, int testonly) if (phylink & PHY_LINK_DUPLEX) { jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT); - ghc |= GHC_DPX; + jwrite32(jme, JME_TXTRHD, TXTRHD_FULLDUPLEX); + jme->reg_ghc |= GHC_DPX; } else { jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT | TXMCS_BACKOFF | TXMCS_CARRIERSENSE | TXMCS_COLLISION); - jwrite32(jme, JME_TXTRHD, TXTRHD_TXPEN | - ((0x2000 << TXTRHD_TXP_SHIFT) & TXTRHD_TXP) | - TXTRHD_TXREN | - ((8 << TXTRHD_TXRL_SHIFT) & TXTRHD_TXRL)); + jwrite32(jme, JME_TXTRHD, TXTRHD_HALFDUPLEX); } - gpreg1 = GPREG1_DEFAULT; + jwrite32(jme, JME_GHC, jme->reg_ghc); + if (is_buggy250(jme->pdev->device, jme->chiprev)) { + jme->reg_gpreg1 &= ~(GPREG1_HALFMODEPATCH | + GPREG1_RSSPATCH); if (!(phylink & PHY_LINK_DUPLEX)) - gpreg1 |= GPREG1_HALFMODEPATCH; + jme->reg_gpreg1 |= GPREG1_HALFMODEPATCH; switch (phylink & PHY_LINK_SPEED_MASK) { case PHY_LINK_SPEED_10M: jme_set_phyfifo_8level(jme); - gpreg1 |= GPREG1_RSSPATCH; + jme->reg_gpreg1 |= GPREG1_RSSPATCH; break; case PHY_LINK_SPEED_100M: jme_set_phyfifo_5level(jme); - gpreg1 |= GPREG1_RSSPATCH; + jme->reg_gpreg1 |= GPREG1_RSSPATCH; break; case PHY_LINK_SPEED_1000M: jme_set_phyfifo_8level(jme); @@ -474,10 +541,7 @@ jme_check_link(struct net_device *netdev, int testonly) break; } } - - jwrite32(jme, JME_GPREG1, gpreg1); - jwrite32(jme, JME_GHC, ghc); - jme->reg_ghc = ghc; + jwrite32(jme, JME_GPREG1, jme->reg_gpreg1); strcat(linkmsg, (phylink & PHY_LINK_DUPLEX) ? "Full-Duplex, " : @@ -616,10 +680,14 @@ jme_enable_tx_engine(struct jme_adapter *jme) * Enable TX Engine */ wmb(); - jwrite32(jme, JME_TXCS, jme->reg_txcs | + jwrite32f(jme, JME_TXCS, jme->reg_txcs | TXCS_SELECT_QUEUE0 | TXCS_ENABLE); + /* + * Start clock for TX MAC Processor + */ + jme_mac_txclk_on(jme); } static inline void @@ -654,6 +722,11 @@ jme_disable_tx_engine(struct jme_adapter *jme) if (!i) pr_err("Disable TX engine timeout\n"); + + /* + * Stop clock for TX MAC Processor + */ + jme_mac_txclk_off(jme); } static void @@ -837,10 +910,15 @@ jme_enable_rx_engine(struct jme_adapter *jme) * Enable RX Engine */ wmb(); - jwrite32(jme, JME_RXCS, jme->reg_rxcs | + jwrite32f(jme, JME_RXCS, jme->reg_rxcs | RXCS_QUEUESEL_Q0 | RXCS_ENABLE | RXCS_QST); + + /* + * Start clock for RX MAC Processor + */ + jme_mac_rxclk_on(jme); } static inline void @@ -877,6 +955,10 @@ jme_disable_rx_engine(struct jme_adapter *jme) if (!i) pr_err("Disable RX engine timeout\n"); + /* + * Stop clock for RX MAC Processor + */ + jme_mac_rxclk_off(jme); } static int @@ -1217,7 +1299,6 @@ jme_link_change_tasklet(unsigned long arg) tasklet_disable(&jme->rxempty_task); if (netif_carrier_ok(netdev)) { - jme_reset_ghc_speed(jme); jme_disable_rx_engine(jme); jme_disable_tx_engine(jme); jme_reset_mac_processor(jme); @@ -1763,7 +1844,6 @@ jme_close(struct net_device *netdev) tasklet_disable(&jme->rxclean_task); tasklet_disable(&jme->rxempty_task); - jme_reset_ghc_speed(jme); jme_disable_rx_engine(jme); jme_disable_tx_engine(jme); jme_reset_mac_processor(jme); @@ -3060,6 +3140,7 @@ jme_init_one(struct pci_dev *pdev, jme->reg_rxmcs = RXMCS_DEFAULT; jme->reg_txpfc = 0; jme->reg_pmcs = PMCS_MFEN; + jme->reg_gpreg1 = GPREG1_DEFAULT; set_bit(JME_FLAG_TXCSUM, &jme->flags); set_bit(JME_FLAG_TSO, &jme->flags); @@ -3226,7 +3307,6 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state) jme_polling_mode(jme); jme_stop_pcc_timer(jme); - jme_reset_ghc_speed(jme); jme_disable_rx_engine(jme); jme_disable_tx_engine(jme); jme_reset_mac_processor(jme); @@ -3242,7 +3322,11 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state) pci_save_state(pdev); jme_powersave_phy(jme); +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27) pci_enable_wake(pdev, PCI_D3hot, true); +#else + pci_pme_active(pdev, true); +#endif pci_set_power_state(pdev, PCI_D3hot); return 0;