aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/igb/igb_main.c
diff options
context:
space:
mode:
authorKim Tatt Chuah <kim.tatt.chuah@intel.com>2017-03-26 20:44:35 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2017-04-20 19:32:45 -0400
commitb90fa8763560aab7c75697fb324ffc73fb813ecc (patch)
treeed8508e766ecae30c81fed64ff77068f694987f9 /drivers/net/ethernet/intel/igb/igb_main.c
parent4827cc37796a02ece7097e01dad8e08f537ac815 (diff)
igb: Enable reading of wake up packet
Currently, in igb_resume(), igb driver ignores the Wake Up Status (WUS) and Wake Up Packet Memory (WUPM) registers. This patch enables the igb driver to read the WUPM if the controller was woken by a wake up packet that is not more than 128 bytes long (maximum WUPM size), then pass it up the kernel network stack. Signed-off-by: Kim Tatt Chuah <kim.tatt.chuah@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igb/igb_main.c')
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 53e66c87abaf..1cf74aa4ebd9 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -7985,6 +7985,36 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake,
7985 return 0; 7985 return 0;
7986} 7986}
7987 7987
7988static void igb_deliver_wake_packet(struct net_device *netdev)
7989{
7990 struct igb_adapter *adapter = netdev_priv(netdev);
7991 struct e1000_hw *hw = &adapter->hw;
7992 struct sk_buff *skb;
7993 u32 wupl;
7994
7995 wupl = rd32(E1000_WUPL) & E1000_WUPL_MASK;
7996
7997 /* WUPM stores only the first 128 bytes of the wake packet.
7998 * Read the packet only if we have the whole thing.
7999 */
8000 if ((wupl == 0) || (wupl > E1000_WUPM_BYTES))
8001 return;
8002
8003 skb = netdev_alloc_skb_ip_align(netdev, E1000_WUPM_BYTES);
8004 if (!skb)
8005 return;
8006
8007 skb_put(skb, wupl);
8008
8009 /* Ensure reads are 32-bit aligned */
8010 wupl = roundup(wupl, 4);
8011
8012 memcpy_fromio(skb->data, hw->hw_addr + E1000_WUPM_REG(0), wupl);
8013
8014 skb->protocol = eth_type_trans(skb, netdev);
8015 netif_rx(skb);
8016}
8017
7988#ifdef CONFIG_PM 8018#ifdef CONFIG_PM
7989#ifdef CONFIG_PM_SLEEP 8019#ifdef CONFIG_PM_SLEEP
7990static int igb_suspend(struct device *dev) 8020static int igb_suspend(struct device *dev)
@@ -8014,7 +8044,7 @@ static int igb_resume(struct device *dev)
8014 struct net_device *netdev = pci_get_drvdata(pdev); 8044 struct net_device *netdev = pci_get_drvdata(pdev);
8015 struct igb_adapter *adapter = netdev_priv(netdev); 8045 struct igb_adapter *adapter = netdev_priv(netdev);
8016 struct e1000_hw *hw = &adapter->hw; 8046 struct e1000_hw *hw = &adapter->hw;
8017 u32 err; 8047 u32 err, val;
8018 8048
8019 pci_set_power_state(pdev, PCI_D0); 8049 pci_set_power_state(pdev, PCI_D0);
8020 pci_restore_state(pdev); 8050 pci_restore_state(pdev);
@@ -8045,6 +8075,10 @@ static int igb_resume(struct device *dev)
8045 */ 8075 */
8046 igb_get_hw_control(adapter); 8076 igb_get_hw_control(adapter);
8047 8077
8078 val = rd32(E1000_WUS);
8079 if (val & WAKE_PKT_WUS)
8080 igb_deliver_wake_packet(netdev);
8081
8048 wr32(E1000_WUS, ~0); 8082 wr32(E1000_WUS, ~0);
8049 8083
8050 rtnl_lock(); 8084 rtnl_lock();