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, 90 insertions, 67 deletions
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 0afe522b8f7b..99e0b4cdc56f 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,25 +637,6 @@ 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
642 */
643#ifdef CONFIG_PM
644static s32 atl1_phy_enter_power_saving(struct atl1_hw *hw)
645{
646/* s32 ret_val;
647 * u16 phy_data;
648 */
649
650/*
651 ret_val = atl1_write_phy_reg(hw, ...);
652 ret_val = atl1_write_phy_reg(hw, ...);
653 ....
654*/
655 return 0;
656}
657#endif
658
659/*
660 * Resets the PHY and make all config validate 640 * Resets the PHY and make all config validate
661 * hw - Struct containing variables accessed by shared code 641 * hw - Struct containing variables accessed by shared code
662 * 642 *
@@ -2027,6 +2007,7 @@ rrd_ok:
2027 /* Good Receive */ 2007 /* Good Receive */
2028 pci_unmap_page(adapter->pdev, buffer_info->dma, 2008 pci_unmap_page(adapter->pdev, buffer_info->dma,
2029 buffer_info->length, PCI_DMA_FROMDEVICE); 2009 buffer_info->length, PCI_DMA_FROMDEVICE);
2010 buffer_info->dma = 0;
2030 skb = buffer_info->skb; 2011 skb = buffer_info->skb;
2031 length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size); 2012 length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size);
2032 2013
@@ -2139,7 +2120,7 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
2139 return -1; 2120 return -1;
2140 } 2121 }
2141 2122
2142 if (skb->protocol == ntohs(ETH_P_IP)) { 2123 if (skb->protocol == htons(ETH_P_IP)) {
2143 struct iphdr *iph = ip_hdr(skb); 2124 struct iphdr *iph = ip_hdr(skb);
2144 2125
2145 real_len = (((unsigned char *)iph - skb->data) + 2126 real_len = (((unsigned char *)iph - skb->data) +
@@ -2784,64 +2765,92 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
2784 struct atl1_hw *hw = &adapter->hw; 2765 struct atl1_hw *hw = &adapter->hw;
2785 u32 ctrl = 0; 2766 u32 ctrl = 0;
2786 u32 wufc = adapter->wol; 2767 u32 wufc = adapter->wol;
2768 u32 val;
2769 int retval;
2770 u16 speed;
2771 u16 duplex;
2787 2772
2788 netif_device_detach(netdev); 2773 netif_device_detach(netdev);
2789 if (netif_running(netdev)) 2774 if (netif_running(netdev))
2790 atl1_down(adapter); 2775 atl1_down(adapter);
2791 2776
2777 retval = pci_save_state(pdev);
2778 if (retval)
2779 return retval;
2780
2792 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); 2781 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
2793 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); 2782 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
2794 if (ctrl & BMSR_LSTATUS) 2783 val = ctrl & BMSR_LSTATUS;
2784 if (val)
2795 wufc &= ~ATLX_WUFC_LNKC; 2785 wufc &= ~ATLX_WUFC_LNKC;
2796 2786
2797 /* reduce speed to 10/100M */ 2787 if (val && wufc) {
2798 if (wufc) { 2788 val = atl1_get_speed_and_duplex(hw, &speed, &duplex);
2799 atl1_phy_enter_power_saving(hw); 2789 if (val) {
2800 /* if resume, let driver to re- setup link */ 2790 if (netif_msg_ifdown(adapter))
2801 hw->phy_configured = false; 2791 dev_printk(KERN_DEBUG, &pdev->dev,
2802 atl1_set_mac_addr(hw); 2792 "error getting speed/duplex\n");
2803 atlx_set_multi(netdev); 2793 goto disable_wol;
2794 }
2804 2795
2805 ctrl = 0; 2796 ctrl = 0;
2806 /* turn on magic packet wol */
2807 if (wufc & ATLX_WUFC_MAG)
2808 ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
2809 2797
2810 /* turn on Link change WOL */ 2798 /* enable magic packet WOL */
2811 if (wufc & ATLX_WUFC_LNKC) 2799 if (wufc & ATLX_WUFC_MAG)
2812 ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); 2800 ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN);
2813 iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); 2801 iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
2802 ioread32(hw->hw_addr + REG_WOL_CTRL);
2803
2804 /* configure the mac */
2805 ctrl = MAC_CTRL_RX_EN;
2806 ctrl |= ((u32)((speed == SPEED_1000) ? MAC_CTRL_SPEED_1000 :
2807 MAC_CTRL_SPEED_10_100) << MAC_CTRL_SPEED_SHIFT);
2808 if (duplex == FULL_DUPLEX)
2809 ctrl |= MAC_CTRL_DUPLX;
2810 ctrl |= (((u32)adapter->hw.preamble_len &
2811 MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
2812 if (adapter->vlgrp)
2813 ctrl |= MAC_CTRL_RMV_VLAN;
2814 if (wufc & ATLX_WUFC_MAG)
2815 ctrl |= MAC_CTRL_BC_EN;
2816 iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL);
2817 ioread32(hw->hw_addr + REG_MAC_CTRL);
2814 2818
2815 /* turn on all-multi mode if wake on multicast is enabled */ 2819 /* poke the PHY */
2816 ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL); 2820 ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
2817 ctrl &= ~MAC_CTRL_DBG; 2821 ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
2818 ctrl &= ~MAC_CTRL_PROMIS_EN; 2822 iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
2819 if (wufc & ATLX_WUFC_MC) 2823 ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
2820 ctrl |= MAC_CTRL_MC_ALL_EN;
2821 else
2822 ctrl &= ~MAC_CTRL_MC_ALL_EN;
2823 2824
2824 /* turn on broadcast mode if wake on-BC is enabled */ 2825 pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
2825 if (wufc & ATLX_WUFC_BC) 2826 goto exit;
2826 ctrl |= MAC_CTRL_BC_EN; 2827 }
2827 else
2828 ctrl &= ~MAC_CTRL_BC_EN;
2829 2828
2830 /* enable RX */ 2829 if (!val && wufc) {
2831 ctrl |= MAC_CTRL_RX_EN; 2830 ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
2832 iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL); 2831 iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
2833 pci_enable_wake(pdev, PCI_D3hot, 1); 2832 ioread32(hw->hw_addr + REG_WOL_CTRL);
2834 pci_enable_wake(pdev, PCI_D3cold, 1); 2833 iowrite32(0, hw->hw_addr + REG_MAC_CTRL);
2835 } else { 2834 ioread32(hw->hw_addr + REG_MAC_CTRL);
2836 iowrite32(0, hw->hw_addr + REG_WOL_CTRL); 2835 hw->phy_configured = false;
2837 pci_enable_wake(pdev, PCI_D3hot, 0); 2836 pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
2838 pci_enable_wake(pdev, PCI_D3cold, 0); 2837 goto exit;
2839 } 2838 }
2840 2839
2841 pci_save_state(pdev); 2840disable_wol:
2841 iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
2842 ioread32(hw->hw_addr + REG_WOL_CTRL);
2843 ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
2844 ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
2845 iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
2846 ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
2847 hw->phy_configured = false;
2848 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
2849exit:
2850 if (netif_running(netdev))
2851 pci_disable_msi(adapter->pdev);
2842 pci_disable_device(pdev); 2852 pci_disable_device(pdev);
2843 2853 pci_set_power_state(pdev, pci_choose_state(pdev, state));
2844 pci_set_power_state(pdev, PCI_D3hot);
2845 2854
2846 return 0; 2855 return 0;
2847} 2856}
@@ -2855,20 +2864,26 @@ static int atl1_resume(struct pci_dev *pdev)
2855 pci_set_power_state(pdev, PCI_D0); 2864 pci_set_power_state(pdev, PCI_D0);
2856 pci_restore_state(pdev); 2865 pci_restore_state(pdev);
2857 2866
2858 /* FIXME: check and handle */
2859 err = pci_enable_device(pdev); 2867 err = pci_enable_device(pdev);
2868 if (err) {
2869 if (netif_msg_ifup(adapter))
2870 dev_printk(KERN_DEBUG, &pdev->dev,
2871 "error enabling pci device\n");
2872 return err;
2873 }
2874
2875 pci_set_master(pdev);
2876 iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
2860 pci_enable_wake(pdev, PCI_D3hot, 0); 2877 pci_enable_wake(pdev, PCI_D3hot, 0);
2861 pci_enable_wake(pdev, PCI_D3cold, 0); 2878 pci_enable_wake(pdev, PCI_D3cold, 0);
2862 2879
2863 iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); 2880 atl1_reset_hw(&adapter->hw);
2864 atl1_reset(adapter); 2881 adapter->cmb.cmb->int_stats = 0;
2865 2882
2866 if (netif_running(netdev)) 2883 if (netif_running(netdev))
2867 atl1_up(adapter); 2884 atl1_up(adapter);
2868 netif_device_attach(netdev); 2885 netif_device_attach(netdev);
2869 2886
2870 atl1_via_workaround(adapter);
2871
2872 return 0; 2887 return 0;
2873} 2888}
2874#else 2889#else
@@ -2876,6 +2891,13 @@ static int atl1_resume(struct pci_dev *pdev)
2876#define atl1_resume NULL 2891#define atl1_resume NULL
2877#endif 2892#endif
2878 2893
2894static void atl1_shutdown(struct pci_dev *pdev)
2895{
2896#ifdef CONFIG_PM
2897 atl1_suspend(pdev, PMSG_SUSPEND);
2898#endif
2899}
2900
2879#ifdef CONFIG_NET_POLL_CONTROLLER 2901#ifdef CONFIG_NET_POLL_CONTROLLER
2880static void atl1_poll_controller(struct net_device *netdev) 2902static void atl1_poll_controller(struct net_device *netdev)
2881{ 2903{
@@ -3122,7 +3144,8 @@ static struct pci_driver atl1_driver = {
3122 .probe = atl1_probe, 3144 .probe = atl1_probe,
3123 .remove = __devexit_p(atl1_remove), 3145 .remove = __devexit_p(atl1_remove),
3124 .suspend = atl1_suspend, 3146 .suspend = atl1_suspend,
3125 .resume = atl1_resume 3147 .resume = atl1_resume,
3148 .shutdown = atl1_shutdown
3126}; 3149};
3127 3150
3128/* 3151/*