ath9k_hw: add the config_pci_powersave AR9003 callback
authorLuis R. Rodriguez <lrodriguez@atheros.com>
Thu, 15 Apr 2010 21:39:02 +0000 (17:39 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 16 Apr 2010 19:43:31 +0000 (15:43 -0400)
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/hw.c

index e6d4c4c8a3df146081ae5276fa95e186dd74e811..0db3475487cba3db3a7ec4698414577769f7542e 100644 (file)
@@ -2594,6 +2594,37 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
 }
 EXPORT_SYMBOL(ath9k_hw_set_interrupts);
 
+/*
+ * Helper for ASPM support.
+ *
+ * Disable PLL when in L0s as well as receiver clock when in L1.
+ * This power saving option must be enabled through the SerDes.
+ *
+ * Programming the SerDes must go through the same 288 bit serial shift
+ * register as the other analog registers.  Hence the 9 writes.
+ */
+static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
+                                        int restore,
+                                        int power_off)
+{
+       if (ah->is_pciexpress != true)
+               return;
+
+       /* Do not touch SerDes registers */
+       if (ah->config.pcie_powersave_enable == 2)
+               return;
+
+       /* Nothing to do on restore for 11N */
+       if (!restore) {
+               /* set bit 19 to allow forcing of pcie core into L1 state */
+               REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+
+               /* Several PCIe massages to ensure proper behaviour */
+               if (ah->config.pcie_waen)
+                       REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
+       }
+}
+
 /*******************/
 /* Beacon Handling */
 /*******************/
@@ -3628,10 +3659,13 @@ static void ar9002_hw_attach_ops(struct ath_hw *ah)
 static void ar9003_hw_attach_ops(struct ath_hw *ah)
 {
        struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+       struct ath_hw_ops *ops = ath9k_hw_ops(ah);
 
        priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
        priv_ops->macversion_supported = ar9003_hw_macversion_supported;
 
+       ops->config_pci_powersave = ar9003_hw_configpcipowersave;
+
        ar9003_hw_attach_phy_ops(ah);
        ar9003_hw_attach_calib_ops(ah);
        ar9003_hw_attach_mac_ops(ah);