aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJay Cliburn <jacliburn@bellsouth.net>2008-05-09 23:12:07 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-13 01:30:24 -0400
commit08e0f1dc8388b3e134c714672c59edc2a7059430 (patch)
treed213ff1fed80abadf05bb66247d7b97ed73e1133 /drivers/net
parentff772b27e5f65c1a186e9f0741f0d00ef7002799 (diff)
atl1: fix broken suspend and resume
Fix atl1_suspend() and atl1_resume() so they actually work. We'll use the suspend function for wake-on-lan in addition to just suspending. Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/atlx/atl1.c125
1 files changed, 80 insertions, 45 deletions
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 3beb44e80ba0..12fb3e5529d1 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -2781,64 +2781,93 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
2781 struct atl1_hw *hw = &adapter->hw; 2781 struct atl1_hw *hw = &adapter->hw;
2782 u32 ctrl = 0; 2782 u32 ctrl = 0;
2783 u32 wufc = adapter->wol; 2783 u32 wufc = adapter->wol;
2784 u32 val;
2785 int retval;
2786 u16 speed;
2787 u16 duplex;
2784 2788
2785 netif_device_detach(netdev); 2789 netif_device_detach(netdev);
2786 if (netif_running(netdev)) 2790 if (netif_running(netdev))
2787 atl1_down(adapter); 2791 atl1_down(adapter);
2788 2792
2793 retval = pci_save_state(pdev);
2794 if (retval)
2795 return retval;
2796
2789 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); 2797 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
2790 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); 2798 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
2791 if (ctrl & BMSR_LSTATUS) 2799 val = ctrl & BMSR_LSTATUS;
2800 if (val)
2792 wufc &= ~ATLX_WUFC_LNKC; 2801 wufc &= ~ATLX_WUFC_LNKC;
2793 2802
2794 /* reduce speed to 10/100M */ 2803 if (val && wufc) {
2795 if (wufc) { 2804 val = atl1_get_speed_and_duplex(hw, &speed, &duplex);
2796 atl1_phy_enter_power_saving(hw); 2805 if (val) {
2797 /* if resume, let driver to re- setup link */ 2806 if (netif_msg_ifdown(adapter))
2798 hw->phy_configured = false; 2807 dev_printk(KERN_DEBUG, &pdev->dev,
2799 atl1_set_mac_addr(hw); 2808 "error getting speed/duplex\n");
2800 atlx_set_multi(netdev); 2809 goto disable_wol;
2810 }
2801 2811
2802 ctrl = 0; 2812 ctrl = 0;
2803 /* turn on magic packet wol */
2804 if (wufc & ATLX_WUFC_MAG)
2805 ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
2806 2813
2807 /* turn on Link change WOL */ 2814 /* enable magic packet WOL */
2808 if (wufc & ATLX_WUFC_LNKC) 2815 if (wufc & ATLX_WUFC_MAG)
2809 ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); 2816 ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN);
2810 iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); 2817 iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
2811 2818 ioread32(hw->hw_addr + REG_WOL_CTRL);
2812 /* turn on all-multi mode if wake on multicast is enabled */ 2819
2813 ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL); 2820 /* configure the mac */
2814 ctrl &= ~MAC_CTRL_DBG; 2821 ctrl = MAC_CTRL_RX_EN;
2815 ctrl &= ~MAC_CTRL_PROMIS_EN; 2822 ctrl |= ((u32)((speed == SPEED_1000) ? MAC_CTRL_SPEED_1000 :
2816 if (wufc & ATLX_WUFC_MC) 2823 MAC_CTRL_SPEED_10_100) << MAC_CTRL_SPEED_SHIFT);
2817 ctrl |= MAC_CTRL_MC_ALL_EN; 2824 if (duplex == FULL_DUPLEX)
2818 else 2825 ctrl |= MAC_CTRL_DUPLX;
2819 ctrl &= ~MAC_CTRL_MC_ALL_EN; 2826 ctrl |= (((u32)adapter->hw.preamble_len &
2820 2827 MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
2821 /* turn on broadcast mode if wake on-BC is enabled */ 2828 if (adapter->vlgrp)
2822 if (wufc & ATLX_WUFC_BC) 2829 ctrl |= MAC_CTRL_RMV_VLAN;
2830 if (wufc & ATLX_WUFC_MAG)
2823 ctrl |= MAC_CTRL_BC_EN; 2831 ctrl |= MAC_CTRL_BC_EN;
2824 else
2825 ctrl &= ~MAC_CTRL_BC_EN;
2826
2827 /* enable RX */
2828 ctrl |= MAC_CTRL_RX_EN;
2829 iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL); 2832 iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL);
2830 pci_enable_wake(pdev, PCI_D3hot, 1); 2833 ioread32(hw->hw_addr + REG_MAC_CTRL);
2831 pci_enable_wake(pdev, PCI_D3cold, 1); 2834
2832 } else { 2835 /* poke the PHY */
2833 iowrite32(0, hw->hw_addr + REG_WOL_CTRL); 2836 ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
2834 pci_enable_wake(pdev, PCI_D3hot, 0); 2837 ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
2835 pci_enable_wake(pdev, PCI_D3cold, 0); 2838 iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
2839 ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
2840
2841 pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
2842 goto exit;
2836 } 2843 }
2837 2844
2838 pci_save_state(pdev); 2845 if (!val && wufc) {
2846 ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
2847 iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
2848 ioread32(hw->hw_addr + REG_WOL_CTRL);
2849 iowrite32(0, hw->hw_addr + REG_MAC_CTRL);
2850 ioread32(hw->hw_addr + REG_MAC_CTRL);
2851 hw->phy_configured = false;
2852 pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
2853 goto exit;
2854 }
2855
2856disable_wol:
2857 iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
2858 ioread32(hw->hw_addr + REG_WOL_CTRL);
2859 ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
2860 ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
2861 iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
2862 ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
2863 atl1_phy_enter_power_saving(hw);
2864 hw->phy_configured = false;
2865 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
2866exit:
2867 if (netif_running(netdev))
2868 pci_disable_msi(adapter->pdev);
2839 pci_disable_device(pdev); 2869 pci_disable_device(pdev);
2840 2870 pci_set_power_state(pdev, pci_choose_state(pdev, state));
2841 pci_set_power_state(pdev, PCI_D3hot);
2842 2871
2843 return 0; 2872 return 0;
2844} 2873}
@@ -2852,20 +2881,26 @@ static int atl1_resume(struct pci_dev *pdev)
2852 pci_set_power_state(pdev, PCI_D0); 2881 pci_set_power_state(pdev, PCI_D0);
2853 pci_restore_state(pdev); 2882 pci_restore_state(pdev);
2854 2883
2855 /* FIXME: check and handle */
2856 err = pci_enable_device(pdev); 2884 err = pci_enable_device(pdev);
2885 if (err) {
2886 if (netif_msg_ifup(adapter))
2887 dev_printk(KERN_DEBUG, &pdev->dev,
2888 "error enabling pci device\n");
2889 return err;
2890 }
2891
2892 pci_set_master(pdev);
2893 iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
2857 pci_enable_wake(pdev, PCI_D3hot, 0); 2894 pci_enable_wake(pdev, PCI_D3hot, 0);
2858 pci_enable_wake(pdev, PCI_D3cold, 0); 2895 pci_enable_wake(pdev, PCI_D3cold, 0);
2859 2896
2860 iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); 2897 atl1_reset_hw(&adapter->hw);
2861 atl1_reset(adapter); 2898 adapter->cmb.cmb->int_stats = 0;
2862 2899
2863 if (netif_running(netdev)) 2900 if (netif_running(netdev))
2864 atl1_up(adapter); 2901 atl1_up(adapter);
2865 netif_device_attach(netdev); 2902 netif_device_attach(netdev);
2866 2903
2867 atl1_via_workaround(adapter);
2868
2869 return 0; 2904 return 0;
2870} 2905}
2871#else 2906#else