summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authordyoung <dyoung@NetBSD.org>2008-06-17 02:01:58 +0000
committerdyoung <dyoung@NetBSD.org>2008-06-17 02:01:58 +0000
commitfac54884d4c2da8b9489f87108cb3f91797a7c73 (patch)
tree678e26603395b3bd36ece5c00b640efff5c736eb /sys/dev
parent842f96408cee6cd161be75e0da174685580c8712 (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.c21
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) {
/*