summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath9k/recv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/recv.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index d373364ef8a9..da0cfe90c38a 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -116,9 +116,6 @@ static void ath_opmode_init(struct ath_softc *sc)
/* configure operational mode */
ath9k_hw_setopmode(ah);
- /* Handle any link-level address change. */
- ath9k_hw_setmac(ah, common->macaddr);
-
/* calculate and install multicast filter */
mfilt[0] = mfilt[1] = ~0;
ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
@@ -295,7 +292,7 @@ static void ath_edma_start_recv(struct ath_softc *sc)
ath_opmode_init(sc);
- ath9k_hw_startpcureceive(sc->sc_ah);
+ ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_SCANNING));
}
static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -501,7 +498,7 @@ int ath_startrecv(struct ath_softc *sc)
start_recv:
spin_unlock_bh(&sc->rx.rxbuflock);
ath_opmode_init(sc);
- ath9k_hw_startpcureceive(ah);
+ ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_SCANNING));
return 0;
}
@@ -1002,8 +999,6 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
struct ieee80211_rx_status *rx_status,
bool *decrypt_error)
{
- struct ath_hw *ah = common->ah;
-
memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
/*
@@ -1018,7 +1013,6 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
if (ath9k_process_rate(common, hw, rx_stats, rx_status))
return -EINVAL;
- rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp);
rx_status->band = hw->conf.channel->band;
rx_status->freq = hw->conf.channel->center_freq;
rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
@@ -1100,6 +1094,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
int dma_type;
u8 rx_status_len = ah->caps.rx_status_len;
+ u64 tsf = 0;
+ u32 tsf_lower = 0;
if (edma)
dma_type = DMA_BIDIRECTIONAL;
@@ -1109,6 +1105,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
spin_lock_bh(&sc->rx.rxbuflock);
+ tsf = ath9k_hw_gettsf64(ah);
+ tsf_lower = tsf & 0xffffffff;
+
do {
/* If handling rx interrupt and flush is in progress => exit */
if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
@@ -1141,6 +1140,15 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
if (flush)
goto requeue;
+ rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
+ if (rs.rs_tstamp > tsf_lower &&
+ unlikely(rs.rs_tstamp - tsf_lower > 0x10000000))
+ rxs->mactime -= 0x100000000ULL;
+
+ if (rs.rs_tstamp < tsf_lower &&
+ unlikely(tsf_lower - rs.rs_tstamp > 0x10000000))
+ rxs->mactime += 0x100000000ULL;
+
retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
rxs, &decrypt_error);
if (retval)