X-Git-Url: http://bbs.cooldavid.org/git/?a=blobdiff_plain;ds=sidebyside;f=jme.c;h=799c2d45505c41528b232a75e73d78d29179c888;hb=472209517465eda83a2ee0e19d75bf5fbd85afd7;hp=612a0585240201ed719add5d8cfe3ca27ef5f846;hpb=186fc2591e3b5b6e35e66aef88e4ef7c4d87fd58;p=jme.git diff --git a/jme.c b/jme.c index 612a058..799c2d4 100644 --- a/jme.c +++ b/jme.c @@ -98,8 +98,7 @@ jme_mdio_write(struct net_device *netdev, wmb(); for (i = JME_PHY_TIMEOUT * 50 ; i > 0 ; --i) { udelay(20); - val = jread32(jme, JME_SMI); - if ((val & SMI_OP_REQ) == 0) + if ((jread32(jme, JME_SMI) & SMI_OP_REQ) == 0) break; } @@ -119,10 +118,11 @@ jme_reset_phy_processor(struct jme_adapter *jme) MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); - jme_mdio_write(jme->dev, - jme->mii_if.phy_id, - MII_CTRL1000, - ADVERTISE_1000FULL | ADVERTISE_1000HALF); + if(jme->pdev->device == JME_GE_DEVICE) + jme_mdio_write(jme->dev, + jme->mii_if.phy_id, + MII_CTRL1000, + ADVERTISE_1000FULL | ADVERTISE_1000HALF); val = jme_mdio_read(jme->dev, jme->mii_if.phy_id, @@ -331,7 +331,7 @@ jme_linkstat_from_phy(struct jme_adapter *jme) phylink = jme_mdio_read(jme->dev, jme->mii_if.phy_id, 17); bmsr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMSR); - if(bmsr & BMCR_ANCOMP) + if(bmsr & BMSR_ANCOMP) phylink |= PHY_LINK_AUTONEG_COMPLETE; return phylink; @@ -522,9 +522,10 @@ jme_free_tx_resources(struct jme_adapter *jme) dev_kfree_skb(txbi->skb); txbi->skb = NULL; } - txbi->mapping = 0; - txbi->len = 0; - txbi->nr_desc = 0; + txbi->mapping = 0; + txbi->len = 0; + txbi->nr_desc = 0; + txbi->start_xmit = 0; } dma_free_coherent(&(jme->pdev->dev), @@ -1329,21 +1330,32 @@ jme_intr_msi(struct jme_adapter *jme, __u32 intrstat) */ jwrite32f(jme, JME_IENC, INTR_ENABLE); - /* - * Write 1 clear interrupt status - */ - jwrite32f(jme, JME_IEVE, intrstat); - if(intrstat & (INTR_LINKCH | INTR_SWINTR)) { + /* + * Link change event is critical + * all other events are ignored + */ + jwrite32(jme, JME_IEVE, intrstat); tasklet_schedule(&jme->linkch_task); goto out_reenable; } - if(intrstat & INTR_TMINTR) + if(intrstat & INTR_TMINTR) { + jwrite32(jme, JME_IEVE, INTR_TMINTR); tasklet_schedule(&jme->pcc_task); + } - if(intrstat & (INTR_PCCTXTO | INTR_PCCTX)) + if(intrstat & (INTR_PCCTXTO | INTR_PCCTX)) { + jwrite32(jme, JME_IEVE, INTR_PCCTXTO | INTR_PCCTX | INTR_TX0); tasklet_schedule(&jme->txclean_task); + } + + if((intrstat & (INTR_PCCRX0TO | INTR_PCCRX0 | INTR_RX0EMP))) { + jwrite32(jme, JME_IEVE, (intrstat & (INTR_PCCRX0TO | + INTR_PCCRX0 | + INTR_RX0EMP)) | + INTR_RX0); + } if(jme->flags & JME_FLAG_POLL) { if(intrstat & INTR_RX0EMP) @@ -1361,8 +1373,7 @@ jme_intr_msi(struct jme_adapter *jme, __u32 intrstat) atomic_inc(&jme->rx_empty); tasklet_schedule(&jme->rxempty_task); } - - if(intrstat & (INTR_PCCRX0TO | INTR_PCCRX0)) + else if(intrstat & (INTR_PCCRX0TO | INTR_PCCRX0)) tasklet_schedule(&jme->rxclean_task); } @@ -1550,6 +1561,20 @@ jme_set_100m_half(struct jme_adapter *jme) jwrite32(jme, JME_GHC, GHC_SPEED_100M); } +#define JME_WAIT_LINK_TIME 2000 /* 2000ms */ +static void +jme_wait_link(struct jme_adapter *jme) +{ + __u32 phylink, to = JME_WAIT_LINK_TIME; + + mdelay(1000); + phylink = jme_linkstat_from_phy(jme); + while(!(phylink & PHY_LINK_UP) && (to -= 10) > 0) { + mdelay(10); + phylink = jme_linkstat_from_phy(jme); + } +} + static void jme_phy_off(struct jme_adapter *jme) { @@ -1794,7 +1819,7 @@ jme_fill_first_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx) txbi->skb = skb; txbi->len = skb->len; if(!(txbi->start_xmit = jiffies)) - txbi->start_xmit = 1; + txbi->start_xmit = (0UL-1); return 0; } @@ -1822,6 +1847,7 @@ jme_stop_queue_if_full(struct jme_adapter *jme) (jiffies - txbi->start_xmit) >= TX_TIMEOUT && txbi->skb)) { netif_stop_queue(jme->dev); + queue_dbg(jme->dev->name, "TX Queue Stopped @(%lu).\n", jiffies); } } @@ -1861,7 +1887,8 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev) jme_map_tx_skb(jme, skb, idx); jme_fill_first_tx_desc(jme, skb, idx); - tx_dbg(jme->dev->name, "Xmit: %d+%d\n", idx, skb_shinfo(skb)->nr_frags + 2); + tx_dbg(jme->dev->name, "Xmit: %d+%d @(%lu)\n", + idx, skb_shinfo(skb)->nr_frags + 2, jiffies); jwrite32(jme, JME_TXCS, jme->reg_txcs | TXCS_SELECT_QUEUE0 | @@ -2457,7 +2484,7 @@ jme_get_eeprom(struct net_device *netdev, int i, offset = eeprom->offset, len = eeprom->len; /* - * ethtool will check boundary for us + * ethtool will check the boundary for us */ eeprom->magic = JME_EEPROM_MAGIC; for(i = 0 ; i < len ; ++i) @@ -2477,7 +2504,7 @@ jme_set_eeprom(struct net_device *netdev, return -EINVAL; /* - * ethtool will check boundary for us + * ethtool will check the boundary for us */ for(i = 0 ; i < len ; ++i) jme_smb_write(jme, i + offset, data[i]); @@ -2689,11 +2716,14 @@ jme_init_one(struct pci_dev *pdev, (unsigned long) jme); jme->dpi.cur = PCC_P1; - jme->reg_ghc = GHC_DPX | GHC_SPEED_1000M; + if(pdev->device == JME_GE_DEVICE) + jme->reg_ghc = GHC_DPX | GHC_SPEED_1000M; + else + jme->reg_ghc = GHC_DPX | GHC_SPEED_100M; jme->reg_rxcs = RXCS_DEFAULT; jme->reg_rxmcs = RXMCS_DEFAULT; jme->reg_txpfc = 0; - jme->reg_pmcs = PMCS_LFEN | PMCS_LREN | PMCS_MFEN; + jme->reg_pmcs = PMCS_MFEN; jme->flags = JME_FLAG_TXCSUM | JME_FLAG_TSO; /* @@ -2740,7 +2770,10 @@ jme_init_one(struct pci_dev *pdev, else { jme->mii_if.phy_id = 1; } - jme->mii_if.supports_gmii = 1; + if(pdev->device == JME_GE_DEVICE) + jme->mii_if.supports_gmii = true; + else + jme->mii_if.supports_gmii = false; jme->mii_if.mdio_read = jme_mdio_read; jme->mii_if.mdio_write = jme_mdio_write; @@ -2841,7 +2874,7 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state) netif_device_detach(netdev); netif_stop_queue(netdev); jme_stop_irq(jme); - jme_free_irq(jme); + //jme_free_irq(jme); while(--timeout > 0 && ( @@ -2857,27 +2890,33 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state) jme_disable_shadow(jme); if(netif_carrier_ok(netdev)) { + if(jme->flags & JME_FLAG_POLL) + jme_polling_mode(jme); + jme_stop_pcc_timer(jme); jme_reset_mac_processor(jme); jme_free_rx_resources(jme); jme_free_tx_resources(jme); netif_carrier_off(netdev); jme->phylink = 0; - - if(jme->flags & JME_FLAG_POLL) - jme_polling_mode(jme); } pci_save_state(pdev); if(jme->reg_pmcs) { jme_set_100m_half(jme); + + if(jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN)) + jme_wait_link(jme); + jwrite32(jme, JME_PMCS, jme->reg_pmcs); + pci_enable_wake(pdev, PCI_D1, true); pci_enable_wake(pdev, PCI_D3hot, true); pci_enable_wake(pdev, PCI_D3cold, true); } else { jme_phy_off(jme); + pci_enable_wake(pdev, PCI_D1, false); pci_enable_wake(pdev, PCI_D3hot, false); pci_enable_wake(pdev, PCI_D3cold, false); } @@ -2902,7 +2941,7 @@ jme_resume(struct pci_dev *pdev) jme_reset_mac_processor(jme); jme_enable_shadow(jme); - jme_request_irq(jme); + //jme_request_irq(jme); jme_start_irq(jme); netif_device_attach(netdev); @@ -2914,7 +2953,8 @@ jme_resume(struct pci_dev *pdev) } static struct pci_device_id jme_pci_tbl[] = { - { PCI_VDEVICE(JMICRON, 0x250) }, + { PCI_VDEVICE(JMICRON, JME_GE_DEVICE) }, + { PCI_VDEVICE(JMICRON, JME_FE_DEVICE) }, { } };