From patchwork Fri Aug 5 11:10:39 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislaw Gruszka X-Patchwork-Id: 1038322 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p75BBYvf004970 for ; Fri, 5 Aug 2011 11:11:34 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754356Ab1HELLc (ORCPT ); Fri, 5 Aug 2011 07:11:32 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59770 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753537Ab1HELLb (ORCPT ); Fri, 5 Aug 2011 07:11:31 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p75BBEOR003072 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 5 Aug 2011 07:11:15 -0400 Received: from localhost (dhcp-27-232.brq.redhat.com [10.34.27.232]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p75BBDA7009281; Fri, 5 Aug 2011 07:11:14 -0400 From: Stanislaw Gruszka To: "John W. Linville" , linux-wireless Cc: ath9k-devel@venema.h4ckr.net, camilo@mesias.co.uk, Jonathan Nieder , Tony Houghton , Rajkumar Manoharan , ath9k-devel@venema.h4ckr.net, Adrian Chadd , Subject: [PATCH -next 8/8] ath9k: be prepare for dynamic ASPM settings change Date: Fri, 5 Aug 2011 13:10:39 +0200 Message-Id: <1312542639-4274-9-git-send-email-sgruszka@redhat.com> In-Reply-To: <1312542639-4274-1-git-send-email-sgruszka@redhat.com> References: <1312542639-4274-1-git-send-email-sgruszka@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 05 Aug 2011 11:11:34 +0000 (UTC) Kernel offer possibility to change ASPM settings using /sys/module/pcie_aspm/parameters/policy interface. As settings can be changed, we also need to change ath9k hw registers. Patch implement this by monitoring power_off state, and based on that state setup register when pci core inform us about ASPM change. Signed-off-by: Stanislaw Gruszka --- drivers/net/wireless/ath/ath9k/hw-ops.h | 1 + drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 3 +- drivers/net/wireless/ath/ath9k/pci.c | 38 +++++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index dd9003e..0743e82 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -24,6 +24,7 @@ static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah, bool power_off) { + ah->power_off = power_off; if (ah->aspm_enabled != true) return; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index f28f339..cb388ff 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -672,6 +672,7 @@ struct ath_hw { bool sw_mgmt_crypto; bool is_pciexpress; bool aspm_enabled; + bool power_off; bool is_monitoring; bool need_an_top2_fixup; u16 tx_trig_level; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index b0389c3..a7e3c5c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1065,6 +1065,8 @@ static int ath9k_start(struct ieee80211_hw *hw) init_channel = ath9k_cmn_get_curchannel(hw, ah); + spin_lock_bh(&sc->sc_pcu_lock); + /* Reset SERDES registers */ ath9k_hw_configpcipowersave(ah, false); @@ -1075,7 +1077,6 @@ static int ath9k_start(struct ieee80211_hw *hw) * be followed by initialization of the appropriate bits * and then setup of the interrupt mask. */ - spin_lock_bh(&sc->sc_pcu_lock); r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); if (r) { ath_err(common, diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 67a2c96..c585180 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -285,6 +285,41 @@ static void ath_pci_remove(struct pci_dev *pdev) pci_release_region(pdev, 0); } +#ifdef CONFIG_PCIEASPM + +static void ath_pci_aspm_changed(struct pci_dev *pdev, u32 state) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct ath_softc *sc = hw->priv; + struct ath_hw *ah = sc->sc_ah; + + spin_lock_irq(&sc->sc_pcu_lock); + + /* + * ASPM settings were changed, we have to configure PCIe PM and SERDES + * registers based on current state of device and new ASPM settings. + */ + if (state & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { + ah->aspm_enabled = true; + ath9k_hw_configpcipowersave(ah, ah->power_off); + } else { + if (ah->power_off == false) { + /* + * Device is enabled, but since we disable ASPM we also + * setup PCIe PM registers in off state. + */ + ath9k_hw_configpcipowersave(ah, true); + /* But track real power_off value. */ + ah->power_off = false; + } + ah->aspm_enabled = false; + } + + spin_unlock_irq(&sc->sc_pcu_lock); +} + +#endif + #ifdef CONFIG_PM static int ath_pci_suspend(struct device *device) @@ -364,6 +399,9 @@ static struct pci_driver ath_pci_driver = { .id_table = ath_pci_id_table, .probe = ath_pci_probe, .remove = ath_pci_remove, +#ifdef CONFIG_PCIEASPM + .aspm_changed = ath_pci_aspm_changed, +#endif .driver.pm = ATH9K_PM_OPS, };