diff options
author | Joerg Albert <jal2@gmx.de> | 2009-09-15 17:27:53 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-10-07 16:39:38 -0400 |
commit | 181af387033e20065e94363d07ecbace7738278c (patch) | |
tree | 7022e3a625e89ac9f1bf55bdf75eb95b88752485 | |
parent | 7c52c07de8bd0433db6b3e0147544e5a2f01b786 (diff) |
ar9170: handle overflow in tsf_low register during get_tsf
ar9170_op_get_tsf: handle a carry from TSF_L into TSF_H
by reading TSF_H twice.
Signed-off-by: Joerg Albert <jal2@gmx.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ar9170/cmd.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/cmd.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/main.c | 24 |
3 files changed, 18 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c index f57a6200167b..cf6f5c4174a6 100644 --- a/drivers/net/wireless/ath/ar9170/cmd.c +++ b/drivers/net/wireless/ath/ar9170/cmd.c | |||
@@ -72,8 +72,7 @@ int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) | |||
72 | return err; | 72 | return err; |
73 | } | 73 | } |
74 | 74 | ||
75 | static int ar9170_read_mreg(struct ar9170 *ar, int nregs, | 75 | int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out) |
76 | const u32 *regs, u32 *out) | ||
77 | { | 76 | { |
78 | int i, err; | 77 | int i, err; |
79 | __le32 *offs, *res; | 78 | __le32 *offs, *res; |
diff --git a/drivers/net/wireless/ath/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h index a4f0e50e52b4..826c45e6b274 100644 --- a/drivers/net/wireless/ath/ar9170/cmd.h +++ b/drivers/net/wireless/ath/ar9170/cmd.h | |||
@@ -44,6 +44,7 @@ | |||
44 | int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len); | 44 | int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len); |
45 | int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val); | 45 | int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val); |
46 | int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val); | 46 | int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val); |
47 | int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out); | ||
47 | int ar9170_echo_test(struct ar9170 *ar, u32 v); | 48 | int ar9170_echo_test(struct ar9170 *ar, u32 v); |
48 | 49 | ||
49 | /* | 50 | /* |
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 81c6cf1135bc..de0ba2bf7691 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -2192,22 +2192,30 @@ static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw) | |||
2192 | { | 2192 | { |
2193 | struct ar9170 *ar = hw->priv; | 2193 | struct ar9170 *ar = hw->priv; |
2194 | int err; | 2194 | int err; |
2195 | u32 tsf_low; | ||
2196 | u32 tsf_high; | ||
2197 | u64 tsf; | 2195 | u64 tsf; |
2196 | #define NR 3 | ||
2197 | static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H, | ||
2198 | AR9170_MAC_REG_TSF_L, | ||
2199 | AR9170_MAC_REG_TSF_H }; | ||
2200 | u32 val[NR]; | ||
2201 | int loops = 0; | ||
2198 | 2202 | ||
2199 | mutex_lock(&ar->mutex); | 2203 | mutex_lock(&ar->mutex); |
2200 | err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low); | 2204 | |
2201 | if (!err) | 2205 | while (loops++ < 10) { |
2202 | err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high); | 2206 | err = ar9170_read_mreg(ar, NR, addr, val); |
2207 | if (err || val[0] == val[2]) | ||
2208 | break; | ||
2209 | } | ||
2210 | |||
2203 | mutex_unlock(&ar->mutex); | 2211 | mutex_unlock(&ar->mutex); |
2204 | 2212 | ||
2205 | if (WARN_ON(err)) | 2213 | if (WARN_ON(err)) |
2206 | return 0; | 2214 | return 0; |
2207 | 2215 | tsf = val[0]; | |
2208 | tsf = tsf_high; | 2216 | tsf = (tsf << 32) | val[1]; |
2209 | tsf = (tsf << 32) | tsf_low; | ||
2210 | return tsf; | 2217 | return tsf; |
2218 | #undef NR | ||
2211 | } | 2219 | } |
2212 | 2220 | ||
2213 | static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 2221 | static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |