Skip to content

Commit

Permalink
ar9170: handle overflow in tsf_low register during get_tsf
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Joerg Albert authored and John W. Linville committed Oct 7, 2009
1 parent 7c52c07 commit 181af38
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 10 deletions.
3 changes: 1 addition & 2 deletions drivers/net/wireless/ath/ar9170/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ar9170/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/*
Expand Down
24 changes: 16 additions & 8 deletions drivers/net/wireless/ath/ar9170/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 181af38

Please sign in to comment.