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>
This commit is contained in:
Joerg Albert 2009-09-15 23:27:53 +02:00 committed by John W. Linville
parent 7c52c07de8
commit 181af38703
3 changed files with 18 additions and 10 deletions

View File

@ -72,8 +72,7 @@ int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
return err;
}
static int ar9170_read_mreg(struct ar9170 *ar, int nregs,
const u32 *regs, u32 *out)
int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out)
{
int i, err;
__le32 *offs, *res;

View File

@ -44,6 +44,7 @@
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_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);
/*

View File

@ -2192,22 +2192,30 @@ static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
{
struct ar9170 *ar = hw->priv;
int err;
u32 tsf_low;
u32 tsf_high;
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);
err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low);
if (!err)
err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high);
while (loops++ < 10) {
err = ar9170_read_mreg(ar, NR, addr, val);
if (err || val[0] == val[2])
break;
}
mutex_unlock(&ar->mutex);
if (WARN_ON(err))
return 0;
tsf = tsf_high;
tsf = (tsf << 32) | tsf_low;
tsf = val[0];
tsf = (tsf << 32) | val[1];
return tsf;
#undef NR
}
static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,