Commit 181af387 authored by Joerg Albert's avatar Joerg Albert Committed by John W. Linville

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: default avatarJoerg Albert <jal2@gmx.de>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 7c52c07d
...@@ -72,8 +72,7 @@ int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) ...@@ -72,8 +72,7 @@ int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
return err; return err;
} }
static int ar9170_read_mreg(struct ar9170 *ar, int nregs, int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out)
const u32 *regs, u32 *out)
{ {
int i, err; int i, err;
__le32 *offs, *res; __le32 *offs, *res;
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len); int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len);
int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val); int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val); int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val);
int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out);
int ar9170_echo_test(struct ar9170 *ar, u32 v); int ar9170_echo_test(struct ar9170 *ar, u32 v);
/* /*
......
...@@ -2192,22 +2192,30 @@ static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw) ...@@ -2192,22 +2192,30 @@ static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
{ {
struct ar9170 *ar = hw->priv; struct ar9170 *ar = hw->priv;
int err; int err;
u32 tsf_low;
u32 tsf_high;
u64 tsf; u64 tsf;
#define NR 3
static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H,
AR9170_MAC_REG_TSF_L,
AR9170_MAC_REG_TSF_H };
u32 val[NR];
int loops = 0;
mutex_lock(&ar->mutex); mutex_lock(&ar->mutex);
err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low);
if (!err) while (loops++ < 10) {
err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high); err = ar9170_read_mreg(ar, NR, addr, val);
if (err || val[0] == val[2])
break;
}
mutex_unlock(&ar->mutex); mutex_unlock(&ar->mutex);
if (WARN_ON(err)) if (WARN_ON(err))
return 0; return 0;
tsf = val[0];
tsf = tsf_high; tsf = (tsf << 32) | val[1];
tsf = (tsf << 32) | tsf_low;
return tsf; return tsf;
#undef NR
} }
static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
......
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