aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 1c01b96c9611..67249c3c9f50 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -644,6 +644,7 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port)
644{ 644{
645 u32 reg1; 645 u32 reg1;
646 646
647 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
647 reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); 648 reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
648 reg1 &= ~phy_power[port]; 649 reg1 &= ~phy_power[port];
649 650
@@ -651,6 +652,7 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port)
651 reg1 |= coma_mode[port]; 652 reg1 |= coma_mode[port];
652 653
653 sky2_pci_write32(hw, PCI_DEV_REG1, reg1); 654 sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
655 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
654 sky2_pci_read32(hw, PCI_DEV_REG1); 656 sky2_pci_read32(hw, PCI_DEV_REG1);
655 657
656 if (hw->chip_id == CHIP_ID_YUKON_FE) 658 if (hw->chip_id == CHIP_ID_YUKON_FE)
@@ -707,9 +709,11 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
707 gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_PDOWN); 709 gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_PDOWN);
708 } 710 }
709 711
712 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
710 reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); 713 reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
711 reg1 |= phy_power[port]; /* set PHY to PowerDown/COMA Mode */ 714 reg1 |= phy_power[port]; /* set PHY to PowerDown/COMA Mode */
712 sky2_pci_write32(hw, PCI_DEV_REG1, reg1); 715 sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
716 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
713} 717}
714 718
715/* Force a renegotiation */ 719/* Force a renegotiation */
@@ -1021,11 +1025,8 @@ static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr,
1021static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2, u16 *slot) 1025static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2, u16 *slot)
1022{ 1026{
1023 struct sky2_tx_le *le = sky2->tx_le + *slot; 1027 struct sky2_tx_le *le = sky2->tx_le + *slot;
1024 struct tx_ring_info *re = sky2->tx_ring + *slot;
1025 1028
1026 *slot = RING_NEXT(*slot, sky2->tx_ring_size); 1029 *slot = RING_NEXT(*slot, sky2->tx_ring_size);
1027 re->flags = 0;
1028 re->skb = NULL;
1029 le->ctrl = 0; 1030 le->ctrl = 0;
1030 return le; 1031 return le;
1031} 1032}
@@ -1618,8 +1619,7 @@ static unsigned tx_le_req(const struct sk_buff *skb)
1618 return count; 1619 return count;
1619} 1620}
1620 1621
1621static void sky2_tx_unmap(struct pci_dev *pdev, 1622static void sky2_tx_unmap(struct pci_dev *pdev, struct tx_ring_info *re)
1622 const struct tx_ring_info *re)
1623{ 1623{
1624 if (re->flags & TX_MAP_SINGLE) 1624 if (re->flags & TX_MAP_SINGLE)
1625 pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr), 1625 pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr),
@@ -1629,6 +1629,7 @@ static void sky2_tx_unmap(struct pci_dev *pdev,
1629 pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr), 1629 pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr),
1630 pci_unmap_len(re, maplen), 1630 pci_unmap_len(re, maplen),
1631 PCI_DMA_TODEVICE); 1631 PCI_DMA_TODEVICE);
1632 re->flags = 0;
1632} 1633}
1633 1634
1634/* 1635/*
@@ -1835,6 +1836,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
1835 dev->stats.tx_packets++; 1836 dev->stats.tx_packets++;
1836 dev->stats.tx_bytes += skb->len; 1837 dev->stats.tx_bytes += skb->len;
1837 1838
1839 re->skb = NULL;
1838 dev_kfree_skb_any(skb); 1840 dev_kfree_skb_any(skb);
1839 1841
1840 sky2->tx_next = RING_NEXT(idx, sky2->tx_ring_size); 1842 sky2->tx_next = RING_NEXT(idx, sky2->tx_ring_size);
@@ -1844,7 +1846,8 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
1844 sky2->tx_cons = idx; 1846 sky2->tx_cons = idx;
1845 smp_mb(); 1847 smp_mb();
1846 1848
1847 if (tx_avail(sky2) > MAX_SKB_TX_LE + 4) 1849 /* Wake unless it's detached, and called e.g. from sky2_down() */
1850 if (tx_avail(sky2) > MAX_SKB_TX_LE + 4 && netif_device_present(dev))
1848 netif_wake_queue(dev); 1851 netif_wake_queue(dev);
1849} 1852}
1850 1853
@@ -2148,7 +2151,9 @@ static void sky2_qlink_intr(struct sky2_hw *hw)
2148 2151
2149 /* reset PHY Link Detect */ 2152 /* reset PHY Link Detect */
2150 phy = sky2_pci_read16(hw, PSM_CONFIG_REG4); 2153 phy = sky2_pci_read16(hw, PSM_CONFIG_REG4);
2154 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
2151 sky2_pci_write16(hw, PSM_CONFIG_REG4, phy | 1); 2155 sky2_pci_write16(hw, PSM_CONFIG_REG4, phy | 1);
2156 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
2152 2157
2153 sky2_link_up(sky2); 2158 sky2_link_up(sky2);
2154} 2159}
@@ -2639,6 +2644,7 @@ static void sky2_hw_intr(struct sky2_hw *hw)
2639 if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) { 2644 if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
2640 u16 pci_err; 2645 u16 pci_err;
2641 2646
2647 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
2642 pci_err = sky2_pci_read16(hw, PCI_STATUS); 2648 pci_err = sky2_pci_read16(hw, PCI_STATUS);
2643 if (net_ratelimit()) 2649 if (net_ratelimit())
2644 dev_err(&pdev->dev, "PCI hardware error (0x%x)\n", 2650 dev_err(&pdev->dev, "PCI hardware error (0x%x)\n",
@@ -2646,12 +2652,14 @@ static void sky2_hw_intr(struct sky2_hw *hw)
2646 2652
2647 sky2_pci_write16(hw, PCI_STATUS, 2653 sky2_pci_write16(hw, PCI_STATUS,
2648 pci_err | PCI_STATUS_ERROR_BITS); 2654 pci_err | PCI_STATUS_ERROR_BITS);
2655 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
2649 } 2656 }
2650 2657
2651 if (status & Y2_IS_PCI_EXP) { 2658 if (status & Y2_IS_PCI_EXP) {
2652 /* PCI-Express uncorrectable Error occurred */ 2659 /* PCI-Express uncorrectable Error occurred */
2653 u32 err; 2660 u32 err;
2654 2661
2662 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
2655 err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS); 2663 err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
2656 sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS, 2664 sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
2657 0xfffffffful); 2665 0xfffffffful);
@@ -2659,6 +2667,7 @@ static void sky2_hw_intr(struct sky2_hw *hw)
2659 dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err); 2667 dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
2660 2668
2661 sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS); 2669 sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
2670 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
2662 } 2671 }
2663 2672
2664 if (status & Y2_HWE_L1_MASK) 2673 if (status & Y2_HWE_L1_MASK)
@@ -3037,6 +3046,7 @@ static void sky2_reset(struct sky2_hw *hw)
3037 } 3046 }
3038 3047
3039 sky2_power_on(hw); 3048 sky2_power_on(hw);
3049 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
3040 3050
3041 for (i = 0; i < hw->ports; i++) { 3051 for (i = 0; i < hw->ports; i++) {
3042 sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); 3052 sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
@@ -3073,6 +3083,7 @@ static void sky2_reset(struct sky2_hw *hw)
3073 reg <<= PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE; 3083 reg <<= PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE;
3074 3084
3075 /* reset PHY Link Detect */ 3085 /* reset PHY Link Detect */
3086 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
3076 sky2_pci_write16(hw, PSM_CONFIG_REG4, 3087 sky2_pci_write16(hw, PSM_CONFIG_REG4,
3077 reg | PSM_CONFIG_REG4_RST_PHY_LINK_DETECT); 3088 reg | PSM_CONFIG_REG4_RST_PHY_LINK_DETECT);
3078 sky2_pci_write16(hw, PSM_CONFIG_REG4, reg); 3089 sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
@@ -3090,6 +3101,7 @@ static void sky2_reset(struct sky2_hw *hw)
3090 /* restore the PCIe Link Control register */ 3101 /* restore the PCIe Link Control register */
3091 sky2_pci_write16(hw, cap + PCI_EXP_LNKCTL, reg); 3102 sky2_pci_write16(hw, cap + PCI_EXP_LNKCTL, reg);
3092 } 3103 }
3104 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
3093 3105
3094 /* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */ 3106 /* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */
3095 sky2_write32(hw, Y2_PEX_PHY_DATA, PEX_DB_ACCESS | (0x08UL << 16)); 3107 sky2_write32(hw, Y2_PEX_PHY_DATA, PEX_DB_ACCESS | (0x08UL << 16));
@@ -3227,6 +3239,27 @@ static inline u8 sky2_wol_supported(const struct sky2_hw *hw)
3227 return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0; 3239 return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0;
3228} 3240}
3229 3241
3242static void sky2_hw_set_wol(struct sky2_hw *hw)
3243{
3244 int wol = 0;
3245 int i;
3246
3247 for (i = 0; i < hw->ports; i++) {
3248 struct net_device *dev = hw->dev[i];
3249 struct sky2_port *sky2 = netdev_priv(dev);
3250
3251 if (sky2->wol)
3252 wol = 1;
3253 }
3254
3255 if (hw->chip_id == CHIP_ID_YUKON_EC_U ||
3256 hw->chip_id == CHIP_ID_YUKON_EX ||
3257 hw->chip_id == CHIP_ID_YUKON_FE_P)
3258 sky2_write32(hw, B0_CTST, wol ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF);
3259
3260 device_set_wakeup_enable(&hw->pdev->dev, wol);
3261}
3262
3230static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 3263static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
3231{ 3264{
3232 const struct sky2_port *sky2 = netdev_priv(dev); 3265 const struct sky2_port *sky2 = netdev_priv(dev);
@@ -3246,13 +3279,7 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
3246 3279
3247 sky2->wol = wol->wolopts; 3280 sky2->wol = wol->wolopts;
3248 3281
3249 if (hw->chip_id == CHIP_ID_YUKON_EC_U || 3282 sky2_hw_set_wol(hw);
3250 hw->chip_id == CHIP_ID_YUKON_EX ||
3251 hw->chip_id == CHIP_ID_YUKON_FE_P)
3252 sky2_write32(hw, B0_CTST, sky2->wol
3253 ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF);
3254
3255 device_set_wakeup_enable(&hw->pdev->dev, sky2->wol);
3256 3283
3257 if (!netif_running(dev)) 3284 if (!netif_running(dev))
3258 sky2_wol_init(sky2); 3285 sky2_wol_init(sky2);
@@ -4684,6 +4711,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
4684 INIT_WORK(&hw->restart_work, sky2_restart); 4711 INIT_WORK(&hw->restart_work, sky2_restart);
4685 4712
4686 pci_set_drvdata(pdev, hw); 4713 pci_set_drvdata(pdev, hw);
4714 pdev->d3_delay = 150;
4687 4715
4688 return 0; 4716 return 0;
4689 4717