Commit 50920a1d authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by Greg Kroah-Hartman

iwlwifi: pcie: enable oscillator for L1 exit

commit 2d93aee1 upstream.

Enabling the oscillator consumes slightly more power (100uA)
but allows to make sure that we exit from L1 on time.

Not doing so might lead to a PCIe specification violation
since we might wake up from L1 at the wrong time.
This issue has been identified on 3160 and 7260 only.
On older NICs L1 off is not enabled, on newer NICs (7265),
the issue is fixed.

When the bug occurs the user sees that the NIC has
disappeared from the PCI bridge, any access to the device
returns 0xff.

This fixes:
	https://bugzilla.kernel.org/show_bug.cgi?id=64541

and has been extensively discussed here:
	http://markmail.org/thread/mfmpzqt3r333n4bo

Fixes: 99cd4714 ("iwlwifi: add 7000 series device configuration")
Reported-and-tested-by: default avatarwzyboy <wzyboy@wzyboy.org>
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 38c963f2
......@@ -260,4 +260,8 @@ static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl)
/*********************** END TX SCHEDULER *************************************/
/* Oscillator clock */
#define OSC_CLK (0xa04068)
#define OSC_CLK_FORCE_CONTROL (0x8)
#endif /* __iwl_prph_h__ */
......@@ -206,6 +206,22 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
goto out;
}
/*
* Enable the oscillator to count wake up time for L1 exit. This
* consumes slightly more power (100uA) - but allows to be sure
* that we wake up from L1 on time.
*
* This looks weird: read twice the same register, discard the
* value, set a bit, and yet again, read that same register
* just to discard the value. But that's the way the hardware
* seems to like it.
*/
iwl_read_prph(trans, OSC_CLK);
iwl_read_prph(trans, OSC_CLK);
iwl_set_bits_prph(trans, OSC_CLK, OSC_CLK_FORCE_CONTROL);
iwl_read_prph(trans, OSC_CLK);
iwl_read_prph(trans, OSC_CLK);
/*
* Enable DMA clock and wait for it to stabilize.
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment