aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000/e1000_ethtool.c
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2006-08-31 17:27:46 -0400
committerAuke Kok <juke-jan.h.kok@intel.com>2006-08-31 17:27:46 -0400
commit120cd57644f85b280b538ee403423641167913a9 (patch)
tree32c35ef6464c0894c6c279d378493c9d6a289402 /drivers/net/e1000/e1000_ethtool.c
parent1db2740d78c74eb11c4d0906047d9c13229a89a4 (diff)
e1000: unify WoL capability detection code
WoL is constantly giving problems and needed a rewrite. Consolidates all WoL capabilities into a single function, and disables WoL for all other ports on the device except for port A. Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Diffstat (limited to 'drivers/net/e1000/e1000_ethtool.c')
-rw-r--r--drivers/net/e1000/e1000_ethtool.c166
1 files changed, 91 insertions, 75 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index ab2f153d5735..04030729882b 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1675,14 +1675,12 @@ e1000_diag_test(struct net_device *netdev,
1675 msleep_interruptible(4 * 1000); 1675 msleep_interruptible(4 * 1000);
1676} 1676}
1677 1677
1678static void 1678static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
1679e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
1680{ 1679{
1681 struct e1000_adapter *adapter = netdev_priv(netdev);
1682 struct e1000_hw *hw = &adapter->hw; 1680 struct e1000_hw *hw = &adapter->hw;
1681 int retval = 1; /* fail by default */
1683 1682
1684 switch (adapter->hw.device_id) { 1683 switch (hw->device_id) {
1685 case E1000_DEV_ID_82542:
1686 case E1000_DEV_ID_82543GC_FIBER: 1684 case E1000_DEV_ID_82543GC_FIBER:
1687 case E1000_DEV_ID_82543GC_COPPER: 1685 case E1000_DEV_ID_82543GC_COPPER:
1688 case E1000_DEV_ID_82544EI_FIBER: 1686 case E1000_DEV_ID_82544EI_FIBER:
@@ -1690,52 +1688,86 @@ e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
1690 case E1000_DEV_ID_82545EM_FIBER: 1688 case E1000_DEV_ID_82545EM_FIBER:
1691 case E1000_DEV_ID_82545EM_COPPER: 1689 case E1000_DEV_ID_82545EM_COPPER:
1692 case E1000_DEV_ID_82546GB_QUAD_COPPER: 1690 case E1000_DEV_ID_82546GB_QUAD_COPPER:
1691 case E1000_DEV_ID_82546GB_PCIE:
1692 /* these don't support WoL at all */
1693 wol->supported = 0; 1693 wol->supported = 0;
1694 wol->wolopts = 0; 1694 break;
1695 return;
1696
1697 case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
1698 /* device id 10B5 port-A supports wol */
1699 if (!adapter->ksp3_port_a) {
1700 wol->supported = 0;
1701 return;
1702 }
1703 /* KSP3 does not suppport UCAST wake-ups for any interface */
1704 wol->supported = WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
1705
1706 if (adapter->wol & E1000_WUFC_EX)
1707 DPRINTK(DRV, ERR, "Interface does not support "
1708 "directed (unicast) frame wake-up packets\n");
1709 wol->wolopts = 0;
1710 goto do_defaults;
1711
1712 case E1000_DEV_ID_82546EB_FIBER: 1695 case E1000_DEV_ID_82546EB_FIBER:
1713 case E1000_DEV_ID_82546GB_FIBER: 1696 case E1000_DEV_ID_82546GB_FIBER:
1714 case E1000_DEV_ID_82571EB_FIBER: 1697 case E1000_DEV_ID_82571EB_FIBER:
1715 /* Wake events only supported on port A for dual fiber */ 1698 case E1000_DEV_ID_82571EB_SERDES:
1699 case E1000_DEV_ID_82571EB_COPPER:
1700 /* Wake events not supported on port B */
1716 if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) { 1701 if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) {
1717 wol->supported = 0; 1702 wol->supported = 0;
1718 wol->wolopts = 0; 1703 break;
1719 return;
1720 } 1704 }
1721 /* Fall Through */ 1705 /* return success for non excluded adapter ports */
1722 1706 retval = 0;
1707 break;
1708 case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
1709 /* quad port adapters only support WoL on port A */
1710 if (!adapter->quad_port_a) {
1711 wol->supported = 0;
1712 break;
1713 }
1714 /* return success for non excluded adapter ports */
1715 retval = 0;
1716 break;
1723 default: 1717 default:
1724 wol->supported = WAKE_UCAST | WAKE_MCAST | 1718 /* dual port cards only support WoL on port A from now on
1725 WAKE_BCAST | WAKE_MAGIC; 1719 * unless it was enabled in the eeprom for port B
1726 wol->wolopts = 0; 1720 * so exclude FUNC_1 ports from having WoL enabled */
1721 if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1 &&
1722 !adapter->eeprom_wol) {
1723 wol->supported = 0;
1724 break;
1725 }
1727 1726
1728do_defaults: 1727 retval = 0;
1729 if (adapter->wol & E1000_WUFC_EX) 1728 }
1730 wol->wolopts |= WAKE_UCAST; 1729
1731 if (adapter->wol & E1000_WUFC_MC) 1730 return retval;
1732 wol->wolopts |= WAKE_MCAST; 1731}
1733 if (adapter->wol & E1000_WUFC_BC) 1732
1734 wol->wolopts |= WAKE_BCAST; 1733static void
1735 if (adapter->wol & E1000_WUFC_MAG) 1734e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
1736 wol->wolopts |= WAKE_MAGIC; 1735{
1736 struct e1000_adapter *adapter = netdev_priv(netdev);
1737
1738 wol->supported = WAKE_UCAST | WAKE_MCAST |
1739 WAKE_BCAST | WAKE_MAGIC;
1740 wol->wolopts = 0;
1741
1742 /* this function will set ->supported = 0 and return 1 if wol is not
1743 * supported by this hardware */
1744 if (e1000_wol_exclusion(adapter, wol))
1737 return; 1745 return;
1746
1747 /* apply any specific unsupported masks here */
1748 switch (adapter->hw.device_id) {
1749 case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
1750 /* KSP3 does not suppport UCAST wake-ups */
1751 wol->supported &= ~WAKE_UCAST;
1752
1753 if (adapter->wol & E1000_WUFC_EX)
1754 DPRINTK(DRV, ERR, "Interface does not support "
1755 "directed (unicast) frame wake-up packets\n");
1756 break;
1757 default:
1758 break;
1738 } 1759 }
1760
1761 if (adapter->wol & E1000_WUFC_EX)
1762 wol->wolopts |= WAKE_UCAST;
1763 if (adapter->wol & E1000_WUFC_MC)
1764 wol->wolopts |= WAKE_MCAST;
1765 if (adapter->wol & E1000_WUFC_BC)
1766 wol->wolopts |= WAKE_BCAST;
1767 if (adapter->wol & E1000_WUFC_MAG)
1768 wol->wolopts |= WAKE_MAGIC;
1769
1770 return;
1739} 1771}
1740 1772
1741static int 1773static int
@@ -1744,52 +1776,36 @@ e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
1744 struct e1000_adapter *adapter = netdev_priv(netdev); 1776 struct e1000_adapter *adapter = netdev_priv(netdev);
1745 struct e1000_hw *hw = &adapter->hw; 1777 struct e1000_hw *hw = &adapter->hw;
1746 1778
1747 switch (adapter->hw.device_id) { 1779 if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
1748 case E1000_DEV_ID_82542: 1780 return -EOPNOTSUPP;
1749 case E1000_DEV_ID_82543GC_FIBER: 1781
1750 case E1000_DEV_ID_82543GC_COPPER: 1782 if (e1000_wol_exclusion(adapter, wol))
1751 case E1000_DEV_ID_82544EI_FIBER:
1752 case E1000_DEV_ID_82546EB_QUAD_COPPER:
1753 case E1000_DEV_ID_82546GB_QUAD_COPPER:
1754 case E1000_DEV_ID_82545EM_FIBER:
1755 case E1000_DEV_ID_82545EM_COPPER:
1756 return wol->wolopts ? -EOPNOTSUPP : 0; 1783 return wol->wolopts ? -EOPNOTSUPP : 0;
1757 1784
1785 switch (hw->device_id) {
1758 case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: 1786 case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
1759 /* device id 10B5 port-A supports wol */
1760 if (!adapter->ksp3_port_a)
1761 return wol->wolopts ? -EOPNOTSUPP : 0;
1762
1763 if (wol->wolopts & WAKE_UCAST) { 1787 if (wol->wolopts & WAKE_UCAST) {
1764 DPRINTK(DRV, ERR, "Interface does not support " 1788 DPRINTK(DRV, ERR, "Interface does not support "
1765 "directed (unicast) frame wake-up packets\n"); 1789 "directed (unicast) frame wake-up packets\n");
1766 return -EOPNOTSUPP; 1790 return -EOPNOTSUPP;
1767 } 1791 }
1768 1792 break;
1769 case E1000_DEV_ID_82546EB_FIBER:
1770 case E1000_DEV_ID_82546GB_FIBER:
1771 case E1000_DEV_ID_82571EB_FIBER:
1772 /* Wake events only supported on port A for dual fiber */
1773 if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
1774 return wol->wolopts ? -EOPNOTSUPP : 0;
1775 /* Fall Through */
1776
1777 default: 1793 default:
1778 if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) 1794 break;
1779 return -EOPNOTSUPP;
1780
1781 adapter->wol = 0;
1782
1783 if (wol->wolopts & WAKE_UCAST)
1784 adapter->wol |= E1000_WUFC_EX;
1785 if (wol->wolopts & WAKE_MCAST)
1786 adapter->wol |= E1000_WUFC_MC;
1787 if (wol->wolopts & WAKE_BCAST)
1788 adapter->wol |= E1000_WUFC_BC;
1789 if (wol->wolopts & WAKE_MAGIC)
1790 adapter->wol |= E1000_WUFC_MAG;
1791 } 1795 }
1792 1796
1797 /* these settings will always override what we currently have */
1798 adapter->wol = 0;
1799
1800 if (wol->wolopts & WAKE_UCAST)
1801 adapter->wol |= E1000_WUFC_EX;
1802 if (wol->wolopts & WAKE_MCAST)
1803 adapter->wol |= E1000_WUFC_MC;
1804 if (wol->wolopts & WAKE_BCAST)
1805 adapter->wol |= E1000_WUFC_BC;
1806 if (wol->wolopts & WAKE_MAGIC)
1807 adapter->wol |= E1000_WUFC_MAG;
1808
1793 return 0; 1809 return 0;
1794} 1810}
1795 1811