Date: Mon, 9 May 2005 04:34:59 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 76728 for review Message-ID: <200505090434.j494Yxnf026649@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=76728 Change 76728 by sam@sam_ebb on 2005/05/09 04:34:28 o more tx fragmentation fixups/cleanups o fixup ath ie addition logic (not entirely right; more tbd) Affected files ... .. //depot/projects/vap/sys/net80211/ieee80211_output.c#10 edit Differences ... ==== //depot/projects/vap/sys/net80211/ieee80211_output.c#10 (text+ko) ==== @@ -63,7 +63,8 @@ static struct mbuf *ieee80211_encap_fastframe(struct ieee80211vap *vap, struct mbuf *m1, const struct ether_header *eh1, struct mbuf *m2, const struct ether_header *eh2); -static int ieee80211_frag(struct ieee80211vap *, struct mbuf *, int hdrsize); +static int ieee80211_fragment(struct ieee80211vap *, struct mbuf *, + u_int hdrsize, u_int ciphdrsize, u_int mtu); #ifdef IEEE80211_DEBUG /* @@ -833,7 +834,8 @@ } /* check if xmit fragmentation is required */ txfrag = (m->m_pkthdr.len > vap->iv_fragthreshold && - !IEEE80211_IS_MULTICAST(wh->i_addr1)); + !IEEE80211_IS_MULTICAST(wh->i_addr1) && + (m->m_flags & M_FF) == 0); /* NB: don't fragment ff's */ if (key != NULL) { /* * IEEE 802.1X: send EAPOL frames always in the clear. @@ -853,7 +855,8 @@ } } } - if (txfrag && !ieee80211_frag(vap, m, hdrsize)) + if (txfrag && !ieee80211_fragment(vap, m, hdrsize, + key != NULL ? key->wk_cipher->ic_header : 0, vap->iv_fragthreshold)) goto bad; IEEE80211_NODE_STAT(ni, tx_data); @@ -997,7 +1000,7 @@ } /* - * Fragment the frame according to the vap's threshold. + * Fragment the frame according to the specified mtu. * The size of the 802.11 header (w/o padding) is provided * so we don't need to recalculate it. We create a new * mbuf for each fragment and chain it through m_nextpkt; @@ -1005,22 +1008,24 @@ * packet's mbufs but that significantly more complicated. */ static int -ieee80211_frag(struct ieee80211vap *vap, struct mbuf *m0, int hdrsize) +ieee80211_fragment(struct ieee80211vap *vap, struct mbuf *m0, + u_int hdrsize, u_int ciphdrsize, u_int mtu) { struct ieee80211_frame *wh, *whf; struct mbuf *m, *prev, *next; - u_int fragno, fragsize, off, remainder; + u_int totalhdrsize, fragno, fragsize, off, remainder; wh = mtod(m0, struct ieee80211_frame *); + totalhdrsize = hdrsize + ciphdrsize; fragno = 1; - off = vap->iv_fragthreshold; + off = mtu - totalhdrsize; remainder = m0->m_pkthdr.len - off; prev = m0; KASSERT(prev->m_nextpkt == NULL, ("mbuf already chained?")); do { fragsize = remainder; - if (fragsize > vap->iv_fragthreshold) - fragsize = vap->iv_fragthreshold; + if (fragsize > mtu) + fragsize = mtu; KASSERT(fragsize < MCLBYTES, ("fragment size %u too big!", fragsize)); if (fragsize > MHLEN) @@ -1029,6 +1034,8 @@ m = m_gethdr(M_DONTWAIT, MT_DATA); if (m == NULL) goto bad; + /* leave room to prepend any cipher header */ + M_ALIGN(m, fragsize - ciphdrsize); /* form the header in the fragment */ whf = mtod(m, struct ieee80211_frame *); @@ -1040,10 +1047,11 @@ /* NB: destination is known to be contiguous */ /* XXX? datapad? */ - m_copydata(m0, off, fragsize - hdrsize, + m_copydata(m0, off, fragsize - totalhdrsize, mtod(m, u_int8_t *) + hdrsize); - m->m_len = fragsize; - m->m_pkthdr.len = fragsize; + m->m_len = fragsize - ciphdrsize; + m->m_pkthdr.len = fragsize - ciphdrsize; + m->m_flags |= M_FRAG; /* chain up the fragment */ prev->m_nextpkt = m; @@ -1052,12 +1060,13 @@ prev = m; /* deduct fragment just formed */ - remainder -= fragsize; - off += fragsize; + remainder -= fragsize - totalhdrsize; + off += fragsize - totalhdrsize; } while (remainder != 0); /* strip first mbuf now that everything has been copied */ - m_adj(m0, m0->m_pkthdr.len - vap->iv_fragthreshold); + m_adj(m0, m0->m_pkthdr.len - mtu); + m0->m_flags |= M_FIRSTFRAG | M_FRAG; return 1; bad: /* reclaim fragments but leave original frame for caller to free */ @@ -1417,11 +1426,12 @@ .ath_defkeyix = { 0x7f, 0xff, }, }; struct ieee80211_ath_ie *ath = (struct ieee80211_ath_ie *) frm; + struct ieee80211vap *vap = ni->ni_vap; memcpy(frm, &info, sizeof(info)); - if (ni->ni_flags & IEEE80211_NODE_FF) + if (IEEE80211_ATH_CAP(vap, ni, FF)) ath->ath_capability |= ATHEROS_CAP_FAST_FRAME; - if (ni->ni_flags & IEEE80211_NODE_TURBOP) + if (IEEE80211_ATH_CAP(vap, ni, TURBOP)) ath->ath_capability |= ATHEROS_CAP_TURBO_PRIME; return frm + sizeof(info); } @@ -1829,7 +1839,7 @@ frm = ieee80211_add_doth(frm, ic); if ((vap->iv_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) frm = ieee80211_add_wme_info(frm, &ic->ic_wme); - if (ni->ni_ath_ie != NULL) /* XXX */ + if (ni->ni_ath_ie != NULL) frm = ieee80211_add_ath(frm, ni); if (vap->iv_opt_ie != NULL) { memcpy(frm, vap->iv_opt_ie, vap->iv_opt_ie_len);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200505090434.j494Yxnf026649>