diff options
| author | dyoung <dyoung@NetBSD.org> | 2008-06-17 02:01:58 +0000 |
|---|---|---|
| committer | dyoung <dyoung@NetBSD.org> | 2008-06-17 02:01:58 +0000 |
| commit | fac54884d4c2da8b9489f87108cb3f91797a7c73 (patch) | |
| tree | 678e26603395b3bd36ece5c00b640efff5c736eb /sys/dev | |
| parent | 842f96408cee6cd161be75e0da174685580c8712 (diff) | |
Repair a discrepancy between the 802.11 standard and ath(4) operation
where transmit fragmentation is concerned.
Extract from ath_tx_start() the code for subtracting padding from
the packet length, creating subroutine deduct_pad_bytes(). Note
that the arithmetic in deduct_pad_bytes() is suspicious.
Use deduct_pad_bytes() to repair the computation of the 802.11
Duration field for fragments. The computation used to leave out
the FCS, among other things.
Some discrepancies between ath(4) operation and the standard may
still remain. According to my observations, the gaps between
transmitted fragments may be approximately 8 microseconds too long.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ic/ath.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/sys/dev/ic/ath.c b/sys/dev/ic/ath.c index 13552bb08a0..7c4639fe82b 100644 --- a/sys/dev/ic/ath.c +++ b/sys/dev/ic/ath.c @@ -1,4 +1,4 @@ -/* $NetBSD: ath.c,v 1.100 2008/05/04 20:02:06 rumble Exp $ */ +/* $NetBSD: ath.c,v 1.101 2008/06/17 02:01:58 dyoung Exp $ */ /*- * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting @@ -41,7 +41,7 @@ __FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.104 2005/09/16 10:09:23 ru Exp $"); #endif #ifdef __NetBSD__ -__KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.100 2008/05/04 20:02:06 rumble Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.101 2008/06/17 02:01:58 dyoung Exp $"); #endif /* @@ -3397,6 +3397,15 @@ ath_freetx(struct mbuf *m) } static int +deduct_pad_bytes(int len, int hdrlen) +{ + /* XXX I am suspicious that this code, which I extracted + * XXX from ath_tx_start() for reuse, does the right thing. + */ + return len - (hdrlen & 3); +} + +static int ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf, struct mbuf *m0) { @@ -3428,7 +3437,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf * Packet length must not include any * pad bytes; deduct them here. */ - pktlen = m0->m_pkthdr.len - (hdrlen & 3); + pktlen = deduct_pad_bytes(m0->m_pkthdr.len, hdrlen); if (iswep) { const struct ieee80211_cipher *cip; @@ -3705,8 +3714,10 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf * the ACK duration */ dur += ath_hal_computetxtime(ah, rt, - m0->m_nextpkt->m_pkthdr.len, - rix, shortPreamble); + deduct_pad_bytes(m0->m_nextpkt->m_pkthdr.len, + hdrlen) - + deduct_pad_bytes(m0->m_pkthdr.len, hdrlen) + pktlen, + rix, shortPreamble); } if (isfrag) { /* |
