diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 54 |
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, | |||
1021 | static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2, u16 *slot) | 1025 | static 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 | ||
1621 | static void sky2_tx_unmap(struct pci_dev *pdev, | 1622 | static 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 | ||
3242 | static 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 | |||
3230 | static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 3263 | static 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 | ||