Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 27 Oct 2012 16:18:11 -0700
From:      Adrian Chadd <adrian@freebsd.org>
To:        freebsd-wireless@freebsd.org
Cc:        FreeBSD Net <freebsd-net@freebsd.org>, freebsd-arch@freebsd.org
Subject:   request for help: 'fixing' the 802.11 TX path
Message-ID:  <CAJ-VmokuUnMOBa6_uD_1=J9DJR38-2L0ETB_7j3Dnx63yCOvnQ@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
Hi all,

I'd like to try and sort out the last remaining niggles in the 802.11
code - this email is focusing on the TX path.

The TX path has a few problems:

* there's a normal versus raw TX path (for raw frames, management
frames, etc) - the raw path doesn't necessarily queue frames into the
raw TX queue, so it's a kind of "side path" to the driver. This causes
frame ordering problems with things like sequence number allocation.
* there's limited locking in the TX path, primarily because you can't
_really_ fine grain lock the TX path. Since you have multiple TX
thread contexts all sending into the same driver queue and that queue
has to share incrementing sequence number, aggregate status and CCMP
encryption replay counters, you _have_ to either use some long-held
mutexes to enforce this _or_ throw all sending into a TX thread and
run that.
* raw TX requires some extra state to be glued (the bpf_params info);
I'd like to glue that into mbufs as an option, so the driver can use
those instead of interpreting their own 802.11 header contents.

And the one I'd like to discuss here:

* Fragment transmission is totally broken and causes mbufs to be just
leaked. The problem with sending fragments (at least for the ath
drivr) is the packet duration calcluation requires the _next_ fragment
to be available.

Now, this is a design hold-over from the previous, pre-vap scheme. The
driver netif would be handed a raw mbuf frame, which it would then
pass through the net80211 encapsulation code and that would
potentially generate 802.11 fragments. The rest of the driver TX path
would then see that it was handed a fragment list and TX those.
Fragments were chained together using m_nextpkt, like a normal mbuf
list.

This doesn't happen any longer. The net80211 vap gets the raw frame,
which then sends that to the driver netif after doing the vap and
802.11 state / encapsulation work. But since all the wifi drivers use
if_start() right now, m_nextpkt gets blanked on both encap and decap..
and thus things leak.

Now I can't really see a way around this, without doing dirty hacks
with mbuf attributes to link the fragments together. The only clean
way I can see is to force all wifi drivers to use if_transmit(), and
then have if_transmit() interpret a chain of frames as "the fragment
list."

I'm tempted to just create a new TX ic method which does what
if_transmit does(), and ignore the if_start/if_transmit stuff
altogether. That way any changes to if_transmit() in the future (where
people may decide to have if_transmit() take a _list_ of frames to
transmit) doesn't screw me. Right now if_transmit() API just sends a
single frame to the driver in question, so I also don't want to abuse
the semantics there to include "oh, and also fragments."

I'd like to get this in soon as I'm going to have to change a bunch of
wireless code in all the drivers as well as the wifi stack and this is
likely going to have some fallout. I'd like to do his before 10.0
branches.

I'm open to suggestions/comments. :-)

Thanks!



Adrian



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-VmokuUnMOBa6_uD_1=J9DJR38-2L0ETB_7j3Dnx63yCOvnQ>