aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/pcie
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2012-12-24 08:01:24 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-01-03 09:29:46 -0500
commit7a65d17053c758109477f420e813ba2d826b0eae (patch)
tree9c53772ba9085c3afc72d75b3091f51fb37cf1ed /drivers/net/wireless/iwlwifi/pcie
parentf317243a8ba1b05338bc03c6606a51021f249a67 (diff)
iwlwifi: virtualize iwl_{grab,release}_nic_access
Since different transports have different ways to wake the up the NIC, we need to virtualize it. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/pcie')
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index e67e179bd04b..80b05d821688 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -759,6 +759,68 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans)
759} 759}
760#endif /* CONFIG_PM_SLEEP */ 760#endif /* CONFIG_PM_SLEEP */
761 761
762static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent)
763{
764 int ret;
765
766 lockdep_assert_held(&trans->reg_lock);
767
768 /* this bit wakes up the NIC */
769 __iwl_set_bit(trans, CSR_GP_CNTRL,
770 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
771
772 /*
773 * These bits say the device is running, and should keep running for
774 * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
775 * but they do not indicate that embedded SRAM is restored yet;
776 * 3945 and 4965 have volatile SRAM, and must save/restore contents
777 * to/from host DRAM when sleeping/waking for power-saving.
778 * Each direction takes approximately 1/4 millisecond; with this
779 * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
780 * series of register accesses are expected (e.g. reading Event Log),
781 * to keep device from sleeping.
782 *
783 * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
784 * SRAM is okay/restored. We don't check that here because this call
785 * is just for hardware register access; but GP1 MAC_SLEEP check is a
786 * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
787 *
788 * 5000 series and later (including 1000 series) have non-volatile SRAM,
789 * and do not save/restore SRAM when power cycling.
790 */
791 ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
792 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
793 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
794 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
795 if (unlikely(ret < 0)) {
796 iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
797 if (!silent) {
798 u32 val = iwl_read32(trans, CSR_GP_CNTRL);
799 WARN_ONCE(1,
800 "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n",
801 val);
802 return false;
803 }
804 }
805
806 return true;
807}
808
809static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans)
810{
811 lockdep_assert_held(&trans->reg_lock);
812 __iwl_clear_bit(trans, CSR_GP_CNTRL,
813 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
814 /*
815 * Above we read the CSR_GP_CNTRL register, which will flush
816 * any previous writes, but we need the write that clears the
817 * MAC_ACCESS_REQ bit to be performed before any other writes
818 * scheduled on different CPUs (after we drop reg_lock).
819 */
820 mmiowb();
821}
822
823
762#define IWL_FLUSH_WAIT_MS 2000 824#define IWL_FLUSH_WAIT_MS 2000
763 825
764static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) 826static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans)
@@ -1238,6 +1300,8 @@ static const struct iwl_trans_ops trans_ops_pcie = {
1238 .write_prph = iwl_trans_pcie_write_prph, 1300 .write_prph = iwl_trans_pcie_write_prph,
1239 .configure = iwl_trans_pcie_configure, 1301 .configure = iwl_trans_pcie_configure,
1240 .set_pmi = iwl_trans_pcie_set_pmi, 1302 .set_pmi = iwl_trans_pcie_set_pmi,
1303 .grab_nic_access = iwl_trans_pcie_grab_nic_access,
1304 .release_nic_access = iwl_trans_pcie_release_nic_access
1241}; 1305};
1242 1306
1243struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, 1307struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,