aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/hw.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2013-11-18 14:14:43 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-12-02 14:25:00 -0500
commit09d8e315d90a70eb1096d68f27be04d6c43724f3 (patch)
tree3d6f1c61739a9660d3b7e12aa2eb44f353a04f6a /drivers/net/wireless/ath/ath9k/hw.c
parent10e2318103f5941aa70c318afe34bc41f1b98529 (diff)
ath9k_hw: fix TSF save/restore around chip reset
A cold reset can be triggered because of DMA stop issues, and this leads to TSF being cleared on all chipsets. To properly deal with this, always save the TSF. Additionally, account for the time it takes to do the actual chip reset, which can be quite significant. On AR9344 it takes around 4.5 ms. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/hw.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 381fbe1d4894..02eff2a8a280 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -17,6 +17,7 @@
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/time.h>
20#include <asm/unaligned.h> 21#include <asm/unaligned.h>
21 22
22#include "hw.h" 23#include "hw.h"
@@ -1855,10 +1856,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1855 struct ath9k_hw_cal_data *caldata, bool fastcc) 1856 struct ath9k_hw_cal_data *caldata, bool fastcc)
1856{ 1857{
1857 struct ath_common *common = ath9k_hw_common(ah); 1858 struct ath_common *common = ath9k_hw_common(ah);
1859 struct timespec ts;
1858 u32 saveLedState; 1860 u32 saveLedState;
1859 u32 saveDefAntenna; 1861 u32 saveDefAntenna;
1860 u32 macStaId1; 1862 u32 macStaId1;
1861 u64 tsf = 0; 1863 u64 tsf = 0;
1864 s64 usec = 0;
1862 int r; 1865 int r;
1863 bool start_mci_reset = false; 1866 bool start_mci_reset = false;
1864 bool save_fullsleep = ah->chip_fullsleep; 1867 bool save_fullsleep = ah->chip_fullsleep;
@@ -1901,10 +1904,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1901 1904
1902 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; 1905 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
1903 1906
1904 /* For chips on which RTC reset is done, save TSF before it gets cleared */ 1907 /* Save TSF before chip reset, a cold reset clears it */
1905 if (AR_SREV_9100(ah) || 1908 tsf = ath9k_hw_gettsf64(ah);
1906 (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))) 1909 getrawmonotonic(&ts);
1907 tsf = ath9k_hw_gettsf64(ah); 1910 usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000;
1908 1911
1909 saveLedState = REG_READ(ah, AR_CFG_LED) & 1912 saveLedState = REG_READ(ah, AR_CFG_LED) &
1910 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | 1913 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
@@ -1937,8 +1940,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1937 } 1940 }
1938 1941
1939 /* Restore TSF */ 1942 /* Restore TSF */
1940 if (tsf) 1943 getrawmonotonic(&ts);
1941 ath9k_hw_settsf64(ah, tsf); 1944 usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000 - usec;
1945 ath9k_hw_settsf64(ah, tsf + usec);
1942 1946
1943 if (AR_SREV_9280_20_OR_LATER(ah)) 1947 if (AR_SREV_9280_20_OR_LATER(ah))
1944 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 1948 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);