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