svn commit: r250974 - head/sys/net80211
Adrian Chadd
adrian at FreeBSD.org
Sat May 25 06:28:31 UTC 2013
Author: adrian
Date: Sat May 25 06:28:30 2013
New Revision: 250974
URL: http://svnweb.freebsd.org/changeset/base/250974
Log:
Fix net80211 fragment creation.
When creating fragment frames, the header length should honour the
DATAPAD flag.
This fixes the fragments that are queued to the ath(4) driver but it
doesn't yet fix fragment transmission. That requires further changes
to the ath(4) transmit path. Well, strictly speaking, it requires
further changes to _all_ wifi driver transmit paths, but this is at least
a start.
Tested:
* AR5416, STA mode, w/ fragthreshold set to 256.
Modified:
head/sys/net80211/ieee80211_output.c
Modified: head/sys/net80211/ieee80211_output.c
==============================================================================
--- head/sys/net80211/ieee80211_output.c Fri May 24 18:59:44 2013 (r250973)
+++ head/sys/net80211/ieee80211_output.c Sat May 25 06:28:30 2013 (r250974)
@@ -1495,18 +1495,28 @@ static int
ieee80211_fragment(struct ieee80211vap *vap, struct mbuf *m0,
u_int hdrsize, u_int ciphdrsize, u_int mtu)
{
+ struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_frame *wh, *whf;
struct mbuf *m, *prev, *next;
u_int totalhdrsize, fragno, fragsize, off, remainder, payload;
+ u_int hdrspace;
KASSERT(m0->m_nextpkt == NULL, ("mbuf already chained?"));
KASSERT(m0->m_pkthdr.len > mtu,
("pktlen %u mtu %u", m0->m_pkthdr.len, mtu));
+ /*
+ * Honor driver DATAPAD requirement.
+ */
+ if (ic->ic_flags & IEEE80211_F_DATAPAD)
+ hdrspace = roundup(hdrsize, sizeof(uint32_t));
+ else
+ hdrspace = hdrsize;
+
wh = mtod(m0, struct ieee80211_frame *);
/* NB: mark the first frag; it will be propagated below */
wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG;
- totalhdrsize = hdrsize + ciphdrsize;
+ totalhdrsize = hdrspace + ciphdrsize;
fragno = 1;
off = mtu - ciphdrsize;
remainder = m0->m_pkthdr.len - off;
@@ -1553,9 +1563,10 @@ ieee80211_fragment(struct ieee80211vap *
payload = fragsize - totalhdrsize;
/* NB: destination is known to be contiguous */
- m_copydata(m0, off, payload, mtod(m, uint8_t *) + hdrsize);
- m->m_len = hdrsize + payload;
- m->m_pkthdr.len = hdrsize + payload;
+
+ m_copydata(m0, off, payload, mtod(m, uint8_t *) + hdrspace);
+ m->m_len = hdrspace + payload;
+ m->m_pkthdr.len = hdrspace + payload;
m->m_flags |= M_FRAG;
/* chain up the fragment */
More information about the svn-src-all
mailing list