Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 May 2013 06:28:30 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r250974 - head/sys/net80211
Message-ID:  <201305250628.r4P6SUIe085327@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201305250628.r4P6SUIe085327>