mirror of
https://github.com/proski/madwifi
synced 2024-11-22 06:21:47 +03:00
Merge RX timestamps changes from madwifi-dfs branch
git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@2859 0192ed92-7a03-0410-a25b-9323aeb14dbd
This commit is contained in:
parent
bd6e91ee85
commit
b2be90d89d
143
ath/if_ath.c
143
ath/if_ath.c
@ -966,6 +966,8 @@ ath_attach(u_int16_t devid, struct net_device *dev, HAL_BUS_TAG tag)
|
||||
DEV_NAME(dev));
|
||||
}
|
||||
|
||||
sc->sc_last_tsf = 0;
|
||||
|
||||
return 0;
|
||||
bad3:
|
||||
ieee80211_ifdetach(ic);
|
||||
@ -1378,15 +1380,31 @@ ath_resume(struct net_device *dev)
|
||||
ath_init(dev);
|
||||
}
|
||||
|
||||
/* Extend 15-bit time stamp from rx descriptor to a full 64-bit TSF
|
||||
* using the current h/w TSF. We no longer make an adjustement since
|
||||
* tsf should always be bf_tsf and bf_tsf is adjusted. */
|
||||
/* Extend 15-bit timestamp from RX descriptor to a full 64-bit TSF using the
|
||||
* provided hardware TSF. The result is the closest value relative to hardware
|
||||
* TSF.
|
||||
*/
|
||||
|
||||
/* NB: Not all chipsets return the same precision rstamp */
|
||||
static __inline u_int64_t
|
||||
ath_extend_tsf(u_int64_t tsf, u_int32_t rstamp)
|
||||
{
|
||||
return ((tsf &~ 0x7fff) | rstamp);
|
||||
#define TSTAMP_MASK 0x7fff
|
||||
|
||||
u_int64_t result;
|
||||
|
||||
result = (tsf & ~TSTAMP_MASK) | rstamp;
|
||||
if (result > tsf) {
|
||||
if (result - tsf > (TSTAMP_MASK/2)) {
|
||||
result -= (TSTAMP_MASK+1);
|
||||
}
|
||||
} else {
|
||||
if (tsf - result > (TSTAMP_MASK/2)) {
|
||||
result += (TSTAMP_MASK+1);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1403,12 +1421,15 @@ ath_uapsd_processtriggers(struct ath_softc *sc)
|
||||
struct ath_txq *uapsd_xmit_q = sc->sc_uapsdq;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
int ac, retval;
|
||||
unsigned long last_rs_tstamp = 0;
|
||||
u_int32_t last_rs_tstamp = 0;
|
||||
int check_for_radar = 0;
|
||||
struct ath_buf *prev_rxbufcur;
|
||||
u_int8_t tid;
|
||||
u_int16_t frame_seq;
|
||||
u_int64_t hw_tsf;
|
||||
int count = 0;
|
||||
int rollover = 0;
|
||||
|
||||
#define PA2DESC(_sc, _pa) \
|
||||
((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
|
||||
((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
|
||||
@ -1482,28 +1503,23 @@ ath_uapsd_processtriggers(struct ath_softc *sc)
|
||||
if (HAL_EINPROGRESS == retval)
|
||||
break;
|
||||
|
||||
/* update the per packet TSF with hw_tsf, hw_tsf is
|
||||
* updated on each RX interrupt, at the start of this
|
||||
* routine. */
|
||||
bf->bf_tsf = hw_tsf;
|
||||
/* If we detect a rollover on rs_tstamp values, then we
|
||||
* know that all packets we have seen already MUST be
|
||||
* decremented by 0x8000 (1<<15) because the last packet
|
||||
* in the queue is for hw_tsf and any rollover we
|
||||
* encounter means prior packets were not tagged with
|
||||
* correct bf_tsf because of this rollover. This
|
||||
* assumes that when rollover happens, we get packets
|
||||
* afterwards. But, if not, we still have TSF values
|
||||
* that do not go backward in time!
|
||||
*/
|
||||
if (rs->rs_tstamp < last_rs_tstamp ||
|
||||
(STAILQ_NEXT(bf, bf_list) == NULL &&
|
||||
ath_extend_tsf(bf->bf_tsf, rs->rs_tstamp) >
|
||||
hw_tsf)) {
|
||||
/* Adjust TSF of this and all prior packets */
|
||||
struct ath_buf *p = sc->sc_rxbufcur;
|
||||
for (;p && p != bf; p = STAILQ_NEXT(p, bf_list))
|
||||
p->bf_tsf -= 0x8000;
|
||||
/* update the per packet TSF with rs_tstamp */
|
||||
bf->bf_tsf = rs->rs_tstamp;
|
||||
bf->bf_status |= ATH_BUFSTATUS_RXTSTAMP;
|
||||
count ++;
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_BEACON,
|
||||
"%s: rs_tstamp=%10llx count=%d\n",
|
||||
DEV_NAME(sc->sc_dev),
|
||||
bf->bf_tsf, count);
|
||||
|
||||
/* compute rollover */
|
||||
if (last_rs_tstamp > rs->rs_tstamp) {
|
||||
rollover ++;
|
||||
DPRINTF(sc, ATH_DEBUG_BEACON,
|
||||
"%s: %d rollover detected\n",
|
||||
DEV_NAME(sc->sc_dev),
|
||||
rollover);
|
||||
}
|
||||
|
||||
last_rs_tstamp = rs->rs_tstamp;
|
||||
@ -1758,6 +1774,57 @@ ath_uapsd_processtriggers(struct ath_softc *sc)
|
||||
}
|
||||
sc->sc_rxbufcur = bf;
|
||||
|
||||
/* SECOND PASS - FIX RX TIMESTAMPS */
|
||||
if (count > 0) {
|
||||
hw_tsf = ath_hal_gettsf64(ah);
|
||||
if (last_rs_tstamp > (hw_tsf & TSTAMP_MASK)) {
|
||||
rollover ++;
|
||||
DPRINTF(sc, ATH_DEBUG_BEACON,
|
||||
"%s: %d rollover detected for hw_tsf=%10llx\n",
|
||||
DEV_NAME(sc->sc_dev),
|
||||
rollover, hw_tsf);
|
||||
}
|
||||
|
||||
last_rs_tstamp = 0;
|
||||
for (bf=prev_rxbufcur; bf; bf = STAILQ_NEXT(bf, bf_list)) {
|
||||
ds = bf->bf_desc;
|
||||
if (ds->ds_link == bf->bf_daddr) {
|
||||
/* NB: never process the self-linked entry at
|
||||
* the end */
|
||||
break;
|
||||
}
|
||||
|
||||
/* we only process buffers who needs RX timestamps
|
||||
* adjustements */
|
||||
|
||||
if (bf->bf_status & ATH_BUFSTATUS_RXTSTAMP) {
|
||||
bf->bf_status &= ~ATH_BUFSTATUS_RXTSTAMP;
|
||||
|
||||
|
||||
/* update rollover */
|
||||
if (last_rs_tstamp > bf->bf_tsf) {
|
||||
rollover --;
|
||||
}
|
||||
|
||||
/* update last_rs_tstamp */
|
||||
last_rs_tstamp = bf->bf_tsf;
|
||||
bf->bf_tsf =(hw_tsf & ~TSTAMP_MASK)|bf->bf_tsf;
|
||||
bf->bf_tsf -= rollover * (TSTAMP_MASK+1);
|
||||
DPRINTF(sc, ATH_DEBUG_BEACON,
|
||||
"%s: bf_tsf=%10llx hw_tsf=%10llx\n",
|
||||
DEV_NAME(sc->sc_dev),
|
||||
bf->bf_tsf, hw_tsf);
|
||||
|
||||
if (bf->bf_tsf < sc->sc_last_tsf) {
|
||||
printk("TSF error: bf_tsf=%10llx sc_last_tsf=%10llx\n",
|
||||
bf->bf_tsf,
|
||||
sc->sc_last_tsf);
|
||||
}
|
||||
sc->sc_last_tsf = bf->bf_tsf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ATH_RXBUF_UNLOCK_IRQ(sc);
|
||||
#undef PA2DESC
|
||||
}
|
||||
@ -5592,8 +5659,9 @@ ath_tx_capture(struct net_device *dev, const struct ath_buf *bf, struct sk_buff
|
||||
}
|
||||
|
||||
/*
|
||||
* Intercept management frames to collect beacon rssi data
|
||||
* and to do ibss merges.
|
||||
* Intercept management frames to collect beacon rssi data and to do
|
||||
* ibss merges. This function is called for all management frames,
|
||||
* including those belonging to other BSS.
|
||||
*/
|
||||
static void
|
||||
ath_recv_mgmt(struct ieee80211_node *ni, struct sk_buff *skb,
|
||||
@ -5680,8 +5748,6 @@ ath_rx_tasklet(TQUEUE_ARG data)
|
||||
unsigned int len;
|
||||
int type;
|
||||
u_int phyerr;
|
||||
u_int64_t rs_tsf;
|
||||
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s\n", __func__);
|
||||
do {
|
||||
@ -5816,12 +5882,7 @@ rx_accept:
|
||||
skb_put(skb, len);
|
||||
skb->protocol = __constant_htons(ETH_P_CONTROL);
|
||||
|
||||
/* Pass up TSF clock in MAC time
|
||||
* Rx descriptor has the low 15 bits of the TSf at
|
||||
* the time the frame was received. Use the current
|
||||
* TSF to extend this to 64 bits. */
|
||||
rs_tsf = ath_extend_tsf(bf->bf_tsf, rs->rs_tstamp);
|
||||
|
||||
/* Pass up TSF clock in MAC time */
|
||||
if (sc->sc_nmonvaps > 0) {
|
||||
/*
|
||||
* Some vap is in monitor mode, so send to
|
||||
@ -5837,7 +5898,7 @@ rx_accept:
|
||||
goto rx_next;
|
||||
}
|
||||
#endif
|
||||
ath_rx_capture(dev, bf, skb, rs_tsf);
|
||||
ath_rx_capture(dev, bf, skb, bf->bf_tsf);
|
||||
if (sc->sc_ic.ic_opmode == IEEE80211_M_MONITOR) {
|
||||
/* no other VAPs need the packet */
|
||||
dev_kfree_skb(skb);
|
||||
@ -5893,7 +5954,7 @@ rx_accept:
|
||||
* grab a reference for processing the frame. */
|
||||
ni = ieee80211_ref_node(ni);
|
||||
ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi);
|
||||
type = ieee80211_input(ni, skb, rs->rs_rssi, rs_tsf);
|
||||
type = ieee80211_input(ni, skb, rs->rs_rssi, bf->bf_tsf);
|
||||
ieee80211_unref_node(&ni);
|
||||
} else {
|
||||
/*
|
||||
@ -5907,7 +5968,7 @@ rx_accept:
|
||||
ieee80211_keyix_t keyix;
|
||||
|
||||
ATH_RSSI_LPF(an->an_avgrssi, rs->rs_rssi);
|
||||
type = ieee80211_input(ni, skb, rs->rs_rssi, rs_tsf);
|
||||
type = ieee80211_input(ni, skb, rs->rs_rssi, bf->bf_tsf);
|
||||
/*
|
||||
* If the station has a key cache slot assigned
|
||||
* update the key->node mapping table.
|
||||
@ -5919,7 +5980,7 @@ rx_accept:
|
||||
an = NULL;
|
||||
ieee80211_unref_node(&ni);
|
||||
} else
|
||||
type = ieee80211_input_all(ic, skb, rs->rs_rssi, rs_tsf);
|
||||
type = ieee80211_input_all(ic, skb, rs->rs_rssi, bf->bf_tsf);
|
||||
}
|
||||
|
||||
if (sc->sc_diversity) {
|
||||
|
@ -430,6 +430,8 @@ struct ath_buf {
|
||||
has already been handled. We may receive
|
||||
multiple interrupts before the rx_tasklet
|
||||
clears the queue */
|
||||
#define ATH_BUFSTATUS_RXTSTAMP 0x00000004 /* RX timestamps needs to be adjusted */
|
||||
|
||||
/* DMA state for tx/rx descriptors. */
|
||||
struct ath_descdma {
|
||||
const char *dd_name;
|
||||
@ -703,6 +705,7 @@ struct ath_softc {
|
||||
#endif
|
||||
u_int sc_slottimeconf; /* manual override for slottime */
|
||||
u_int64_t sc_tsf; /* TSF at last rx interrupt */
|
||||
u_int64_t sc_last_tsf;
|
||||
};
|
||||
|
||||
typedef void (*ath_callback) (struct ath_softc *);
|
||||
|
Loading…
Reference in New Issue
Block a user