From patchwork Wed Oct 21 09:52:49 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naohiro Ooiwa X-Patchwork-Id: 36518 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 1CF45B7B9A for ; Wed, 21 Oct 2009 21:26:11 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753267AbZJUK0A (ORCPT ); Wed, 21 Oct 2009 06:26:00 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753264AbZJUK0A (ORCPT ); Wed, 21 Oct 2009 06:26:00 -0400 Received: from mailgw.miraclelinux.com ([122.216.84.157]:11498 "EHLO mailgw.miraclelinux.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753243AbZJUKZ7 (ORCPT ); Wed, 21 Oct 2009 06:25:59 -0400 X-Greylist: delayed 1994 seconds by postgrey-1.27 at vger.kernel.org; Wed, 21 Oct 2009 06:25:59 EDT Received: from mailgw.miraclelinux.com (localhost.localdomain [127.0.0.1]) by localhost (Postfix) with SMTP id 84D19D2F74; Wed, 21 Oct 2009 18:52:49 +0900 (JST) Received: from localhost.localdomain (dhcp-0161.miraclelinux.com [10.1.0.161]) by mailgw.miraclelinux.com (Postfix) with ESMTP id 61E79D2F5C; Wed, 21 Oct 2009 18:52:49 +0900 (JST) Message-ID: <4ADED9F1.4060308@miraclelinux.com> Date: Wed, 21 Oct 2009 18:52:49 +0900 From: Naohiro Ooiwa User-Agent: Thunderbird 2.0.0.14 (X11/20080501) MIME-Version: 1.0 To: "netdev@vger.kernel.org" , e1000-devel@lists.sourceforge.net, svaidy@linux.vnet.ibm.com, linux-kernel-owner@vger.kernel.org Subject: [PATCH] e1000: the power down when running ifdown command Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Hi all I'm trying to modify e1000 driver for power saving. The e1000 driver doesn't let the power down when running ifdown command. So, I set to the D3hot state of a PCI device at the end of e1000_close(). With this modification, e1000 driver reduces power by ifdown to the same level as link-down case. I spoke it in Collaboration Summit 2009. For details and result of power measurement, please refer the 36-38 page of following document. http://events.linuxfoundation.org/archive/lfcs09_ooiwa.pdf Could you please check the my patch ? Should I consider WOL ? Dosen't E1000_PCI_POWER_SAVE need ? Hi Vaidy I was glad that you talked to me in Collaboration Summit. I'm sorry for sending the patch so late. I found a bug in the patch which I used in Collaboration Summit. Sometimes, it's don't work to auto-negotiation by repeated ifup and ifdown. I fixed it. I'd appreciate it if you could test. Thanks you. Naohiro Ooiwa Signed-off-by: Naohiro Ooiwa --- drivers/net/e1000/e1000_main.c | 32 ++++++++++++++++++++++++++++++++ 1 files changed, 32 insertions(+), 0 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index bcd192c..12e1a42 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -26,6 +26,11 @@ *******************************************************************************/ +/* + * define this if you want pci save power while ifdown. + */ +#define E1000_PCI_POWER_SAVE + #include "e1000.h" #include @@ -1248,6 +1253,23 @@ static int e1000_open(struct net_device *netdev) struct e1000_hw *hw = &adapter->hw; int err; +#ifdef E1000_PCI_POWER_SAVE + struct pci_dev *pdev = adapter->pdev; + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + + if (adapter->need_ioport) + err = pci_enable_device(pdev); + else + err = pci_enable_device_mem(pdev); + if (err) { + printk(KERN_ERR "e1000: Cannot enable PCI device from power-save\n"); + return err; + } + pci_set_master(pdev); +#endif + /* disallow open during test */ if (test_bit(__E1000_TESTING, &adapter->flags)) return -EBUSY; @@ -1265,6 +1287,7 @@ static int e1000_open(struct net_device *netdev) goto err_setup_rx; e1000_power_up_phy(adapter); + e1000_reset(adapter); adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; if ((hw->mng_cookie.status & @@ -1341,6 +1364,15 @@ static int e1000_close(struct net_device *netdev) e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); } +#ifdef E1000_PCI_POWER_SAVE +#ifdef CONFIG_PM + pci_save_state(adapter->pdev); +#endif + pci_disable_device(adapter->pdev); + pci_wake_from_d3(adapter->pdev, true); + pci_set_power_state(adapter->pdev, PCI_D3hot); +#endif + return 0; }