aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/atlx/atl1.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/atlx/atl1.c')
-rw-r--r--drivers/net/atlx/atl1.c157
1 files changed, 98 insertions, 59 deletions
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 0afe522b8f7b..9c2394d49428 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. 2 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
3 * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com> 3 * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
4 * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com> 4 * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
5 * 5 *
6 * Derived from Intel e1000 driver 6 * Derived from Intel e1000 driver
7 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. 7 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
@@ -36,7 +36,6 @@
36 * A very incomplete list of things that need to be dealt with: 36 * A very incomplete list of things that need to be dealt with:
37 * 37 *
38 * TODO: 38 * TODO:
39 * Wake on LAN.
40 * Add more ethtool functions. 39 * Add more ethtool functions.
41 * Fix abstruse irq enable/disable condition described here: 40 * Fix abstruse irq enable/disable condition described here:
42 * http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2 41 * http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2
@@ -638,21 +637,18 @@ static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw)
638} 637}
639 638
640/* 639/*
641 *TODO: do something or get rid of this 640 * Force the PHY into power saving mode using vendor magic.
642 */ 641 */
643#ifdef CONFIG_PM 642#ifdef CONFIG_PM
644static s32 atl1_phy_enter_power_saving(struct atl1_hw *hw) 643static void atl1_phy_enter_power_saving(struct atl1_hw *hw)
645{ 644{
646/* s32 ret_val; 645 atl1_write_phy_reg(hw, MII_DBG_ADDR, 0);
647 * u16 phy_data; 646 atl1_write_phy_reg(hw, MII_DBG_DATA, 0x124E);
648 */ 647 atl1_write_phy_reg(hw, MII_DBG_ADDR, 2);
648 atl1_write_phy_reg(hw, MII_DBG_DATA, 0x3000);
649 atl1_write_phy_reg(hw, MII_DBG_ADDR, 3);
650 atl1_write_phy_reg(hw, MII_DBG_DATA, 0);
649 651
650/*
651 ret_val = atl1_write_phy_reg(hw, ...);
652 ret_val = atl1_write_phy_reg(hw, ...);
653 ....
654*/
655 return 0;
656} 652}
657#endif 653#endif
658 654
@@ -2784,64 +2780,93 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
2784 struct atl1_hw *hw = &adapter->hw; 2780 struct atl1_hw *hw = &adapter->hw;
2785 u32 ctrl = 0; 2781 u32 ctrl = 0;
2786 u32 wufc = adapter->wol; 2782 u32 wufc = adapter->wol;
2783 u32 val;
2784 int retval;
2785 u16 speed;
2786 u16 duplex;
2787 2787
2788 netif_device_detach(netdev); 2788 netif_device_detach(netdev);
2789 if (netif_running(netdev)) 2789 if (netif_running(netdev))
2790 atl1_down(adapter); 2790 atl1_down(adapter);
2791 2791
2792 retval = pci_save_state(pdev);
2793 if (retval)
2794 return retval;
2795
2792 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); 2796 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
2793 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); 2797 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
2794 if (ctrl & BMSR_LSTATUS) 2798 val = ctrl & BMSR_LSTATUS;
2799 if (val)
2795 wufc &= ~ATLX_WUFC_LNKC; 2800 wufc &= ~ATLX_WUFC_LNKC;
2796 2801
2797 /* reduce speed to 10/100M */ 2802 if (val && wufc) {
2798 if (wufc) { 2803 val = atl1_get_speed_and_duplex(hw, &speed, &duplex);
2799 atl1_phy_enter_power_saving(hw); 2804 if (val) {
2800 /* if resume, let driver to re- setup link */ 2805 if (netif_msg_ifdown(adapter))
2801 hw->phy_configured = false; 2806 dev_printk(KERN_DEBUG, &pdev->dev,
2802 atl1_set_mac_addr(hw); 2807 "error getting speed/duplex\n");
2803 atlx_set_multi(netdev); 2808 goto disable_wol;
2809 }
2804 2810
2805 ctrl = 0; 2811 ctrl = 0;
2806 /* turn on magic packet wol */
2807 if (wufc & ATLX_WUFC_MAG)
2808 ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
2809 2812
2810 /* turn on Link change WOL */ 2813 /* enable magic packet WOL */
2811 if (wufc & ATLX_WUFC_LNKC) 2814 if (wufc & ATLX_WUFC_MAG)
2812 ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); 2815 ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN);
2813 iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); 2816 iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
2814 2817 ioread32(hw->hw_addr + REG_WOL_CTRL);
2815 /* turn on all-multi mode if wake on multicast is enabled */ 2818
2816 ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL); 2819 /* configure the mac */
2817 ctrl &= ~MAC_CTRL_DBG; 2820 ctrl = MAC_CTRL_RX_EN;
2818 ctrl &= ~MAC_CTRL_PROMIS_EN; 2821 ctrl |= ((u32)((speed == SPEED_1000) ? MAC_CTRL_SPEED_1000 :
2819 if (wufc & ATLX_WUFC_MC) 2822 MAC_CTRL_SPEED_10_100) << MAC_CTRL_SPEED_SHIFT);
2820 ctrl |= MAC_CTRL_MC_ALL_EN; 2823 if (duplex == FULL_DUPLEX)
2821 else 2824 ctrl |= MAC_CTRL_DUPLX;
2822 ctrl &= ~MAC_CTRL_MC_ALL_EN; 2825 ctrl |= (((u32)adapter->hw.preamble_len &
2823 2826 MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
2824 /* turn on broadcast mode if wake on-BC is enabled */ 2827 if (adapter->vlgrp)
2825 if (wufc & ATLX_WUFC_BC) 2828 ctrl |= MAC_CTRL_RMV_VLAN;
2829 if (wufc & ATLX_WUFC_MAG)
2826 ctrl |= MAC_CTRL_BC_EN; 2830 ctrl |= MAC_CTRL_BC_EN;
2827 else
2828 ctrl &= ~MAC_CTRL_BC_EN;
2829
2830 /* enable RX */
2831 ctrl |= MAC_CTRL_RX_EN;
2832 iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL); 2831 iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL);
2833 pci_enable_wake(pdev, PCI_D3hot, 1); 2832 ioread32(hw->hw_addr + REG_MAC_CTRL);
2834 pci_enable_wake(pdev, PCI_D3cold, 1); 2833
2835 } else { 2834 /* poke the PHY */
2836 iowrite32(0, hw->hw_addr + REG_WOL_CTRL); 2835 ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
2837 pci_enable_wake(pdev, PCI_D3hot, 0); 2836 ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
2838 pci_enable_wake(pdev, PCI_D3cold, 0); 2837 iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
2838 ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
2839
2840 pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
2841 goto exit;
2839 } 2842 }
2840 2843
2841 pci_save_state(pdev); 2844 if (!val && wufc) {
2845 ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
2846 iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
2847 ioread32(hw->hw_addr + REG_WOL_CTRL);
2848 iowrite32(0, hw->hw_addr + REG_MAC_CTRL);
2849 ioread32(hw->hw_addr + REG_MAC_CTRL);
2850 hw->phy_configured = false;
2851 pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
2852 goto exit;
2853 }
2854
2855disable_wol:
2856 iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
2857 ioread32(hw->hw_addr + REG_WOL_CTRL);
2858 ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
2859 ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
2860 iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
2861 ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
2862 atl1_phy_enter_power_saving(hw);
2863 hw->phy_configured = false;
2864 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
2865exit:
2866 if (netif_running(netdev))
2867 pci_disable_msi(adapter->pdev);
2842 pci_disable_device(pdev); 2868 pci_disable_device(pdev);
2843 2869 pci_set_power_state(pdev, pci_choose_state(pdev, state));
2844 pci_set_power_state(pdev, PCI_D3hot);
2845 2870
2846 return 0; 2871 return 0;
2847} 2872}
@@ -2855,20 +2880,26 @@ static int atl1_resume(struct pci_dev *pdev)
2855 pci_set_power_state(pdev, PCI_D0); 2880 pci_set_power_state(pdev, PCI_D0);
2856 pci_restore_state(pdev); 2881 pci_restore_state(pdev);
2857 2882
2858 /* FIXME: check and handle */
2859 err = pci_enable_device(pdev); 2883 err = pci_enable_device(pdev);
2884 if (err) {
2885 if (netif_msg_ifup(adapter))
2886 dev_printk(KERN_DEBUG, &pdev->dev,
2887 "error enabling pci device\n");
2888 return err;
2889 }
2890
2891 pci_set_master(pdev);
2892 iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
2860 pci_enable_wake(pdev, PCI_D3hot, 0); 2893 pci_enable_wake(pdev, PCI_D3hot, 0);
2861 pci_enable_wake(pdev, PCI_D3cold, 0); 2894 pci_enable_wake(pdev, PCI_D3cold, 0);
2862 2895
2863 iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); 2896 atl1_reset_hw(&adapter->hw);
2864 atl1_reset(adapter); 2897 adapter->cmb.cmb->int_stats = 0;
2865 2898
2866 if (netif_running(netdev)) 2899 if (netif_running(netdev))
2867 atl1_up(adapter); 2900 atl1_up(adapter);
2868 netif_device_attach(netdev); 2901 netif_device_attach(netdev);
2869 2902
2870 atl1_via_workaround(adapter);
2871
2872 return 0; 2903 return 0;
2873} 2904}
2874#else 2905#else
@@ -2876,6 +2907,13 @@ static int atl1_resume(struct pci_dev *pdev)
2876#define atl1_resume NULL 2907#define atl1_resume NULL
2877#endif 2908#endif
2878 2909
2910static void atl1_shutdown(struct pci_dev *pdev)
2911{
2912#ifdef CONFIG_PM
2913 atl1_suspend(pdev, PMSG_SUSPEND);
2914#endif
2915}
2916
2879#ifdef CONFIG_NET_POLL_CONTROLLER 2917#ifdef CONFIG_NET_POLL_CONTROLLER
2880static void atl1_poll_controller(struct net_device *netdev) 2918static void atl1_poll_controller(struct net_device *netdev)
2881{ 2919{
@@ -3122,7 +3160,8 @@ static struct pci_driver atl1_driver = {
3122 .probe = atl1_probe, 3160 .probe = atl1_probe,
3123 .remove = __devexit_p(atl1_remove), 3161 .remove = __devexit_p(atl1_remove),
3124 .suspend = atl1_suspend, 3162 .suspend = atl1_suspend,
3125 .resume = atl1_resume 3163 .resume = atl1_resume,
3164 .shutdown = atl1_shutdown
3126}; 3165};
3127 3166
3128/* 3167/*